mirror of https://github.com/espruino/BangleApps
Merge branch 'master' into master
commit
2c6248c031
|
@ -1,2 +1,4 @@
|
|||
0.02: Fix deletion of apps - now use files list in app.info (fix #262)
|
||||
0.03: Add support for data files
|
||||
0.04: Add functionality to sort apps manually or alphabetically ascending/descending.
|
||||
0.05: Tweaks to help with memory usage
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
const storage = require('Storage');
|
||||
const store = require('Storage');
|
||||
|
||||
const boolFormat = (v) => v ? "On" : "Off";
|
||||
|
||||
let m;
|
||||
|
||||
function showMainMenu() {
|
||||
const mainmenu = {
|
||||
'': {
|
||||
|
@ -12,25 +10,29 @@ function showMainMenu() {
|
|||
'Free': {
|
||||
value: undefined,
|
||||
format: (v) => {
|
||||
return storage.getFree();
|
||||
return store.getFree();
|
||||
},
|
||||
onchange: () => {}
|
||||
},
|
||||
'Compact': () => {
|
||||
E.showMessage('Compacting...');
|
||||
try {
|
||||
storage.compact();
|
||||
store.compact();
|
||||
} catch (e) {
|
||||
}
|
||||
m = showMainMenu();
|
||||
showMainMenu();
|
||||
},
|
||||
'Apps': ()=> m = showApps(),
|
||||
'Apps': ()=> showApps(),
|
||||
'Sort Apps': () => showSortAppsMenu(),
|
||||
'< Back': ()=> {load();}
|
||||
};
|
||||
return E.showMenu(mainmenu);
|
||||
E.showMenu(mainmenu);
|
||||
}
|
||||
|
||||
function isGlob(f) {
|
||||
return /[?*]/.test(f);
|
||||
}
|
||||
|
||||
function isGlob(f) {return /[?*]/.test(f)}
|
||||
function globToRegex(pattern) {
|
||||
const ESCAPE = '.*+-?^${}()|[]\\';
|
||||
const regex = pattern.replace(/./g, c => {
|
||||
|
@ -44,40 +46,41 @@ function globToRegex(pattern) {
|
|||
}
|
||||
|
||||
function eraseFiles(app) {
|
||||
app.files.split(",").forEach(f=>storage.erase(f));
|
||||
app.files.split(",").forEach(f=>store.erase(f));
|
||||
}
|
||||
|
||||
function eraseData(app) {
|
||||
if(!app.data) return;
|
||||
const d=app.data.split(';'),
|
||||
files=d[0].split(','),
|
||||
sFiles=(d[1]||'').split(',');
|
||||
let erase = f=>storage.erase(f);
|
||||
let erase = f=>store.erase(f);
|
||||
files.forEach(f=>{
|
||||
if (!isGlob(f)) erase(f);
|
||||
else storage.list(globToRegex(f)).forEach(erase);
|
||||
})
|
||||
erase = sf=>storage.open(sf,'r').erase();
|
||||
else store.list(globToRegex(f)).forEach(erase);
|
||||
});
|
||||
erase = sf=>store.open(sf,'r').erase();
|
||||
sFiles.forEach(sf=>{
|
||||
if (!isGlob(sf)) erase(sf);
|
||||
else storage.list(globToRegex(sf+'\u0001'))
|
||||
else store.list(globToRegex(sf+'\u0001'))
|
||||
.forEach(fs=>erase(fs.substring(0,fs.length-1)));
|
||||
})
|
||||
});
|
||||
}
|
||||
function eraseApp(app, files,data) {
|
||||
E.showMessage('Erasing\n' + app.name + '...');
|
||||
if (files) eraseFiles(app)
|
||||
if (data) eraseData(app)
|
||||
if (files) eraseFiles(app);
|
||||
if (data) eraseData(app);
|
||||
}
|
||||
function eraseOne(app, files,data){
|
||||
E.showPrompt('Erase\n'+app.name+'?').then((v) => {
|
||||
if (v) {
|
||||
Bangle.buzz(100, 1);
|
||||
eraseApp(app, files,data)
|
||||
eraseApp(app, files, data);
|
||||
showApps();
|
||||
} else {
|
||||
showAppMenu(app)
|
||||
showAppMenu(app);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
function eraseAll(apps, files,data) {
|
||||
E.showPrompt('Erase all?').then((v) => {
|
||||
|
@ -87,7 +90,7 @@ function eraseAll(apps, files,data) {
|
|||
eraseApp(apps[n], files,data);
|
||||
}
|
||||
showApps();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function showAppMenu(app) {
|
||||
|
@ -95,16 +98,16 @@ function showAppMenu(app) {
|
|||
'': {
|
||||
'title': app.name,
|
||||
},
|
||||
'< Back': () => m = showApps(),
|
||||
}
|
||||
'< Back': () => showApps(),
|
||||
};
|
||||
if (app.data) {
|
||||
appmenu['Erase Completely'] = () => eraseOne(app, true, true)
|
||||
appmenu['Erase App,Keep Data'] = () => eraseOne(app,true, false)
|
||||
appmenu['Only Erase Data'] = () => eraseOne(app,false, true)
|
||||
appmenu['Erase Completely'] = () => eraseOne(app, true, true);
|
||||
appmenu['Erase App,Keep Data'] = () => eraseOne(app, true, false);
|
||||
appmenu['Only Erase Data'] = () => eraseOne(app, false, true);
|
||||
} else {
|
||||
appmenu['Erase'] = () => eraseOne(app,true, false)
|
||||
appmenu['Erase'] = () => eraseOne(app, true, false);
|
||||
}
|
||||
return E.showMenu(appmenu);
|
||||
E.showMenu(appmenu);
|
||||
}
|
||||
|
||||
function showApps() {
|
||||
|
@ -112,20 +115,20 @@ function showApps() {
|
|||
'': {
|
||||
'title': 'Apps',
|
||||
},
|
||||
'< Back': () => m = showMainMenu(),
|
||||
'< Back': () => showMainMenu(),
|
||||
};
|
||||
|
||||
var list = storage.list(/\.info$/).filter((a)=> {
|
||||
var list = store.list(/\.info$/).filter((a)=> {
|
||||
return a !== 'setting.info';
|
||||
}).sort().map((app) => {
|
||||
var ret = storage.readJSON(app,1)||{};
|
||||
var ret = store.readJSON(app,1)||{};
|
||||
ret[''] = app;
|
||||
return ret;
|
||||
});
|
||||
|
||||
if (list.length > 0) {
|
||||
list.reduce((menu, app) => {
|
||||
menu[app.name] = () => m = showAppMenu(app);
|
||||
menu[app.name] = () => showAppMenu(app);
|
||||
return menu;
|
||||
}, appsmenu);
|
||||
appsmenu['Erase All'] = () => {
|
||||
|
@ -144,7 +147,82 @@ function showApps() {
|
|||
onchange: ()=> {}
|
||||
};
|
||||
}
|
||||
return E.showMenu(appsmenu);
|
||||
E.showMenu(appsmenu);
|
||||
}
|
||||
|
||||
m = showMainMenu();
|
||||
function showSortAppsMenu() {
|
||||
const sorterMenu = {
|
||||
'': {
|
||||
'title': 'App Sorter',
|
||||
},
|
||||
'< Back': () => showMainMenu(),
|
||||
'Sort: manually': ()=> showSortAppsManually(),
|
||||
'Sort: alph. ASC': () => {
|
||||
E.showMessage('Sorting:\nAlphabetically\nascending ...');
|
||||
sortAlphabet(false);
|
||||
},
|
||||
'Sort: alph. DESC': () => {
|
||||
E.showMessage('Sorting:\nAlphabetically\ndescending ...');
|
||||
sortAlphabet(true);
|
||||
}
|
||||
};
|
||||
E.showMenu(sorterMenu);
|
||||
}
|
||||
|
||||
function showSortAppsManually() {
|
||||
const appsSorterMenu = {
|
||||
'': {
|
||||
'title': 'Sort: manually',
|
||||
},
|
||||
'< Back': () => showSortAppsMenu(),
|
||||
};
|
||||
let appList = getAppsList();
|
||||
if (appList.length > 0) {
|
||||
appList.reduce((menu, app) => {
|
||||
menu[app.name] = {
|
||||
value: app.sortorder || 0,
|
||||
min: 0,
|
||||
max: appList.length,
|
||||
step: 1,
|
||||
onchange: val => setSortorder(app, val)
|
||||
};
|
||||
return menu;
|
||||
}, appsSorterMenu);
|
||||
} else {
|
||||
appsSorterMenu['...No Apps...'] = {
|
||||
value: undefined,
|
||||
format: ()=> '',
|
||||
onchange: ()=> {}
|
||||
};
|
||||
}
|
||||
E.showMenu(appsSorterMenu);
|
||||
}
|
||||
|
||||
function setSortorder(app, val) {
|
||||
app = store.readJSON(app.id + '.info', 1);
|
||||
app.sortorder = val;
|
||||
store.writeJSON(app.id + '.info', app);
|
||||
}
|
||||
|
||||
function getAppsList() {
|
||||
return store.list('.info').map((a)=> {
|
||||
let app = store.readJSON(a, 1) || {};
|
||||
if (app.type !== 'widget') {
|
||||
return {id: app.id, name: app.name, sortorder: app.sortorder};
|
||||
}
|
||||
}).filter((a) => a).sort(sortHelper());
|
||||
}
|
||||
|
||||
function sortAlphabet(desc) {
|
||||
let appsSorted = desc ? getAppsList().reverse() : getAppsList();
|
||||
appsSorted.forEach((a, i) => {
|
||||
setSortorder(a, i);
|
||||
});
|
||||
showSortAppsMenu();
|
||||
}
|
||||
|
||||
function sortHelper() {
|
||||
return (a, b) => (a.name > b.name) - (a.name < b.name);
|
||||
}
|
||||
|
||||
showMainMenu();
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0.01: First Version
|
|
@ -0,0 +1,7 @@
|
|||
# Get Up
|
||||
|
||||
Reminds you to getup every x minutes (default: 20).
|
||||
|
||||
Sitting to long is dangerous!
|
||||
|
||||
Sit and move time configurable in settings.
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A75wACCJugAAguaGBouFGCwuF53NFxem6PX6/R0wwVF4xgJEwOsFoMrlYDB1gwUL55dCFQIvE65hUL54jBRgQvF6JgaRxQpCF4SUC67BV5ouLF40yGAOBF64ANR4vXwJhCR6oABq4ACF5TvDAAOsL4LvS4wuGGBi6DGIYuSAAQvGMJiSC6JdSGAovPGAQAFXSQvDrgrBqwvMGAzqTF4d/F4owLADKQGmQv/F7eAF4UySQQwn0ZcCq0ylkySFYyDMEgvDvQwFAAYvk0aLBqy/CAAaUhSAi+BX4QzCAwJkgF4eAX4gzDSsIvDeIzFlGAhhEF9QAHBwIwvF8IwSF7oxMF8gALSEQwRF/4v/YH4v/GD4usAH4A/AH4ARA="))
|
|
@ -0,0 +1,45 @@
|
|||
//init settings
|
||||
const storage = require("Storage");
|
||||
const SETTINGS_FILE = 'getup.settings.json';
|
||||
|
||||
function setting(key) {
|
||||
const DEFAULTS = {
|
||||
'sitTime' : 20,
|
||||
'moveTime' : 1
|
||||
}
|
||||
if (!settings) {
|
||||
loadSettings();
|
||||
}
|
||||
return (key in settings) ? settings[key] : DEFAULTS[key];
|
||||
}
|
||||
|
||||
let settings;
|
||||
|
||||
function loadSettings() {
|
||||
settings = storage.readJSON(SETTINGS_FILE, 1) || {};
|
||||
}
|
||||
|
||||
//vibrate, draw move message and start timer for sitting message
|
||||
function remind() {
|
||||
Bangle.buzz(1000,1);
|
||||
g.clear();
|
||||
g.setFont("8x12",4);
|
||||
g.setColor(0x03E0);
|
||||
g.drawString("MOVE!", g.getWidth()/2, g.getHeight()/2);
|
||||
setTimeout(print_message,setting("moveTime") * 60000);
|
||||
}
|
||||
//draw sitting message and start timer for reminder
|
||||
function print_message(){
|
||||
g.clear();
|
||||
g.setFont("8x12",2);
|
||||
g.setColor(0xF800);
|
||||
g.drawString("sitting is dangerous!", g.getWidth()/2, g.getHeight()/2);
|
||||
setTimeout(remind,setting("sitTime") * 60000);
|
||||
}
|
||||
|
||||
//init graphics
|
||||
require("Font8x12").add(Graphics);
|
||||
g.setFontAlign(0,0);
|
||||
g.flip();
|
||||
|
||||
print_message();
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,48 @@
|
|||
// This file should contain exactly one function, which shows the app's settings
|
||||
/**
|
||||
* @param {function} back Use back() to return to settings menu
|
||||
*/
|
||||
(function(back) {
|
||||
const SETTINGS_FILE = 'getup.settings.json';
|
||||
|
||||
// initialize with default settings...
|
||||
let s = {
|
||||
'sitTime' : 20,
|
||||
'moveTime' : 1
|
||||
};
|
||||
// ...and overwrite them with any saved values
|
||||
// This way saved values are preserved if a new version adds more settings
|
||||
const storage = require('Storage');
|
||||
const saved = storage.readJSON(SETTINGS_FILE, 1) || {};
|
||||
for (const key in saved) {
|
||||
s[key] = saved[key];
|
||||
}
|
||||
|
||||
// creates a function to safe a specific setting, e.g. save('color')(1)
|
||||
function save(key) {
|
||||
return function (value) {
|
||||
s[key] = value;
|
||||
storage.write(SETTINGS_FILE, s);
|
||||
};
|
||||
}
|
||||
|
||||
const menu = {
|
||||
'': { 'title': 'Get Up' },
|
||||
'< Back': back,
|
||||
'Sit time (min)': {
|
||||
value: s.sitTime,
|
||||
min: 0,
|
||||
max: 10000,
|
||||
step: 1,
|
||||
onchange: save('sitTime'),
|
||||
},
|
||||
'Move time (min)': {
|
||||
value: s.moveTime,
|
||||
min: 0,
|
||||
max: 5000,
|
||||
step: 1,
|
||||
onchange: save('moveTime'),
|
||||
},
|
||||
};
|
||||
E.showMenu(menu);
|
||||
});
|
|
@ -3,3 +3,5 @@
|
|||
0.03: Add {msb:true} so that on new builds, color is correct for 16 bit
|
||||
0.04: Fix hour alignment for single digits
|
||||
Scaling for background images <240px wide
|
||||
0.05: Fix memory/interval leak when LCD turns on
|
||||
0.06: Support 12 hour time
|
|
@ -3,6 +3,7 @@ Draws a fullscreen image from flash memory
|
|||
Saves a small image to flash which is just the area where the clock is
|
||||
Keeps an offscreen buffer and draws the time to that
|
||||
*/
|
||||
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
|
||||
var inf = require("Storage").readJSON("imgclock.face.json");
|
||||
var img = require("Storage").read("imgclock.face.img");
|
||||
var IX = inf.x, IY = inf.y, IBPP = inf.bpp;
|
||||
|
@ -29,6 +30,12 @@ if (!bgimg || !bgimg.length) createBgImg();
|
|||
|
||||
function draw() {
|
||||
var t = new Date();
|
||||
var hours = t.getHours();
|
||||
var meridian = "";
|
||||
if (is12Hour) {
|
||||
meridian = (hours < 12) ? "AM" : "PM";
|
||||
hours = ((hours + 11) % 12) + 1;
|
||||
}
|
||||
// quickly set background image
|
||||
new Uint8Array(cg.buffer).set(bgimg);
|
||||
// draw time
|
||||
|
@ -36,7 +43,7 @@ function draw() {
|
|||
var x = 40;
|
||||
cg.setFont("7x11Numeric7Seg",3);
|
||||
cg.setFontAlign(1,-1);
|
||||
cg.drawString(t.getHours(), x, 0);
|
||||
cg.drawString(hours, x, 0);
|
||||
x+=2;
|
||||
cg.fillRect(x, 10, x+2, 10+2).fillRect(x, 20, x+2, 20+2);
|
||||
x+=6;
|
||||
|
@ -46,6 +53,7 @@ function draw() {
|
|||
cg.setFont("7x11Numeric7Seg",1);
|
||||
cg.drawString(("0"+t.getSeconds()).substr(-2), x, 20);
|
||||
cg.setFont("6x8",1);
|
||||
cg.drawString(meridian, x+2, 0);
|
||||
cg.setFontAlign(0,-1);
|
||||
cg.drawString(locale.date(t),IW/2,IH-8);
|
||||
// draw to screen
|
||||
|
@ -65,7 +73,7 @@ Bangle.on('lcdPower',on=>{
|
|||
if (secondInterval) clearInterval(secondInterval);
|
||||
secondInterval = undefined;
|
||||
if (on) {
|
||||
setInterval(draw,1000);
|
||||
secondInterval = setInterval(draw,1000);
|
||||
draw();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
0.01: Init
|
||||
0.02: fix 3/4 moon orientation
|
||||
|
|
|
@ -55,7 +55,7 @@ function drawMoon(d) {
|
|||
},
|
||||
// 3/4 ascending
|
||||
4: () => {
|
||||
moon[7]();
|
||||
moon[3]();
|
||||
g.setColor(MOON).fillEllipse(
|
||||
moonX - moonR / 2,
|
||||
moonY - moonR,
|
||||
|
@ -70,7 +70,7 @@ function drawMoon(d) {
|
|||
},
|
||||
// 3/4 descending
|
||||
6: () => {
|
||||
moon[3]();
|
||||
moon[7]();
|
||||
g.setColor(MOON).fillEllipse(
|
||||
moonX - moonR / 2,
|
||||
moonY - moonR,
|
||||
|
|
|
@ -9,6 +9,7 @@ const distanceUnits = { // how many meters per X?
|
|||
const speedUnits = { // how many kph per X?
|
||||
"kmh": 1,
|
||||
"kph": 1,
|
||||
"km/h": 1,
|
||||
"mph": 1.60934
|
||||
};
|
||||
|
||||
|
@ -129,9 +130,9 @@ var locales = {
|
|||
thousands_sep: ",",
|
||||
currency_symbol: "$",
|
||||
int_curr_symbol: "CAD",
|
||||
speed: "mph",
|
||||
distance: { 0: "mi", 1: "kmi" },
|
||||
temperature: "°F",
|
||||
speed: "km/h",
|
||||
distance: { 0: "m", 1: "km" },
|
||||
temperature: "°C",
|
||||
ampm: { 0: "am", 1: "pm" },
|
||||
timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%A, %B %d, %Y", "1": "%Y-%m-%d" }, // Sunday, March 1, 2020 // 2012-12-20
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
0.01: New App!
|
||||
0.02: Watch vibrates with every beat
|
||||
0.03: Uses mean of three time intervalls to calculate bmp
|
||||
0.04: App shows instructions, Widgets remain visible, color changed
|
||||
|
|
|
@ -10,7 +10,7 @@ function changecolor() {
|
|||
const maxColors = 2;
|
||||
const colors = {
|
||||
0: { value: 0xFFFF, name: "White" },
|
||||
1: { value: 0x000F, name: "Navy" },
|
||||
// 1: { value: 0x000F, name: "Navy" },
|
||||
// 2: { value: 0x03E0, name: "DarkGreen" },
|
||||
// 3: { value: 0x03EF, name: "DarkCyan" },
|
||||
// 4: { value: 0x7800, name: "Maroon" },
|
||||
|
@ -21,7 +21,7 @@ function changecolor() {
|
|||
// 9: { value: 0x001F, name: "Blue" },
|
||||
// 10: { value: 0x07E0, name: "Green" },
|
||||
// 11: { value: 0x07FF, name: "Cyan" },
|
||||
// 12: { value: 0xF800, name: "Red" },
|
||||
1: { value: 0xF800, name: "Red" },
|
||||
// 13: { value: 0xF81F, name: "Magenta" },
|
||||
// 14: { value: 0xFFE0, name: "Yellow" },
|
||||
// 15: { value: 0xFFFF, name: "White" },
|
||||
|
@ -40,11 +40,11 @@ function changecolor() {
|
|||
}
|
||||
|
||||
function updateScreen() {
|
||||
g.clear();
|
||||
g.clearRect(0, 50, 250, 150);
|
||||
changecolor();
|
||||
Bangle.buzz(50, 0.75);
|
||||
g.setFont("Vector",48);
|
||||
g.drawString(Math.floor(bpm)+"bpm", -1, 70);
|
||||
g.drawString(Math.floor(bpm)+"bpm", 5, 60);
|
||||
}
|
||||
|
||||
Bangle.on('touch', function(button) {
|
||||
|
@ -66,10 +66,8 @@ Bangle.on('touch', function(button) {
|
|||
|
||||
tStart = Date.now();
|
||||
clearInterval(time_diff);
|
||||
g.clear();
|
||||
g.setFont("Vector",48);
|
||||
bpm = (60 * 1000/(time_diff));
|
||||
g.drawString(Math.floor(bpm)+"bpm", -1, 70);
|
||||
updateScreen();
|
||||
clearInterval(interval);
|
||||
interval = setInterval(updateScreen, 60000 / bpm);
|
||||
return bpm;
|
||||
|
@ -91,3 +89,9 @@ setWatch(() => {
|
|||
}, BTN3, {repeat:true});
|
||||
|
||||
interval = setInterval(updateScreen, 60000 / bpm);
|
||||
|
||||
g.clear();
|
||||
g.drawString('Touch the screen to set tempo.\nUse BTN1 to increase, and\nBTN3 to decrease bpm value by 1.', 15, 150);
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: Add posibillity to generate Wifi code.
|
|
@ -3,8 +3,28 @@
|
|||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Enter a URL: <input type="text" id="url" class="form-input" value="http://espruino.com"></p>
|
||||
<input type="radio" id="useURL" name="mode" checked/>
|
||||
<label for="useURL">Use URL:</label>
|
||||
<input type="text" id="url" class="form-input" value="http://espruino.com">
|
||||
<hr>
|
||||
<input type="radio" id="useWIFI" name="mode"/>
|
||||
<label for="useWIFI">Use Wifi Credentials:</label>
|
||||
<input type="text" id="ssid" class="form-input" value="">
|
||||
<p>Wifi password: <input type="password" id="password" class="form-input" value=""></p>
|
||||
<div class="form-group">
|
||||
<label for="encryption" class="control-label">Encryption</label>
|
||||
<div class="input-group">
|
||||
<select name="encryption" id="encryption" class="form-control">
|
||||
<option value="WPA">WPA/WPA2</option>
|
||||
<option value="WEP">WEP</option>
|
||||
<option value="nopass">None</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="hidden" name="hidden"/>
|
||||
<label for="hidden">Wifi is hidden</label>
|
||||
</div>
|
||||
<p>Try your QR Code: <div id="qrcode"></div></p>
|
||||
<p>Click <button id="upload" class="btn btn-primary">Upload</button></p>
|
||||
|
||||
|
@ -14,31 +34,72 @@
|
|||
<script src="../../lib/imageconverter.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
var qrcode = new QRCode("qrcode", {
|
||||
text: document.getElementById("url").value,
|
||||
width: 200,
|
||||
height: 200,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
});
|
||||
|
||||
document.getElementById("url").addEventListener("change", function() {
|
||||
//https://github.com/evgeni/qifi/blob/gh-pages/index.html#L168
|
||||
function escapeString (string) {
|
||||
var to_escape = ['\\', ';', ',', ':', '"'];
|
||||
var hex_only = /^[0-9a-f]+$/i;
|
||||
var output = "";
|
||||
for (var i=0; i<string.length; i++) {
|
||||
if(string[i].includes(to_escape)) {
|
||||
output += '\\'+string[i];
|
||||
}
|
||||
else {
|
||||
output += string[i];
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
function generateWifiString(ssid, password, hidden,encryption){
|
||||
//https://github.com/evgeni/qifi/blob/gh-pages/index.html#L198
|
||||
var qrstring = 'WIFI:S:'+escapeString(ssid)+';T:'+encryption+';P:'+escapeString(password)+';';
|
||||
if (hidden) {
|
||||
qrstring += 'H:true';
|
||||
}
|
||||
return qrstring;
|
||||
}
|
||||
function refreshQRCode(){
|
||||
qrcode.clear(); // clear the code.
|
||||
qrcode.makeCode(document.getElementById("url").value); // make another code.
|
||||
if(document.getElementById("useWIFI").checked){
|
||||
const ssid = document.getElementById("ssid").value;
|
||||
const password = document.getElementById("password").value;
|
||||
const encryption = document.getElementById("encryption").value;
|
||||
const hidden = document.getElementById("hidden").checked;
|
||||
const wifiString = generateWifiString(ssid, password, hidden, encryption);
|
||||
qrcode.makeCode(wifiString);
|
||||
}else{
|
||||
qrcode.makeCode(document.getElementById("url").value);
|
||||
}
|
||||
}
|
||||
var qrcode = new QRCode("qrcode", {
|
||||
text: document.getElementById("url").value,
|
||||
width: 200,
|
||||
height: 200,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
});
|
||||
|
||||
document.getElementById("url").addEventListener("change", refreshQRCode);
|
||||
document.getElementById("ssid").addEventListener("change",refreshQRCode);
|
||||
document.getElementById("password").addEventListener("change",refreshQRCode);
|
||||
document.getElementById("encryption").addEventListener("change",refreshQRCode);
|
||||
document.getElementById("hidden").addEventListener("change",refreshQRCode);
|
||||
document.getElementById("useURL").addEventListener("change",refreshQRCode);
|
||||
document.getElementById("useWIFI").addEventListener("change",refreshQRCode);
|
||||
document.getElementById("upload").addEventListener("click", function() {
|
||||
var url = document.getElementById("url").value;
|
||||
var content = document.getElementById("url").value;
|
||||
if(document.getElementById("useWIFI").checked){
|
||||
content = document.getElementById("ssid").value
|
||||
}
|
||||
var img = imageconverter.canvastoString(document.getElementsByTagName("canvas")[0],{mode:"1bit",output:"string",compression:true});
|
||||
var app = `var img = ${img};
|
||||
var url = ${JSON.stringify(url)};
|
||||
var content = ${JSON.stringify(content)};
|
||||
g.setColor(1,1,1);
|
||||
g.fillRect(0,0,239,239);
|
||||
g.drawImage(img,20,20);
|
||||
g.setFontAlign(0,0);
|
||||
g.setFont("6x8");
|
||||
g.setColor(0,0,0);
|
||||
g.drawString(url,120,230);
|
||||
g.drawString(content,120,230);
|
||||
g.setColor(1,1,1);
|
||||
`;
|
||||
sendCustomizedApp({
|
||||
|
|
|
@ -218,6 +218,12 @@ function refreshLibrary() {
|
|||
if (versionInfo) versionInfo = " <small>("+versionInfo+")</small>";
|
||||
var readme = `<a class="c-hand" onclick="showReadme('${app.id}')">Read more...</a>`;
|
||||
var favourite = favourites.find(e => e == app.id);
|
||||
|
||||
var username = "espruino";
|
||||
var githubMatch = window.location.href.match(/\/(\w+)\.github\.io/);
|
||||
if(githubMatch) username = githubMatch[1];
|
||||
var url = `https://github.com/${username}/BangleApps/tree/master/apps/${app.id}`;
|
||||
|
||||
return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
||||
<div class="tile-icon">
|
||||
<figure class="avatar"><img src="apps/${app.icon?`${app.id}/${app.icon}`:"unknown.png"}" alt="${escapeHtml(app.name)}"></figure><br/>
|
||||
|
@ -225,7 +231,7 @@ function refreshLibrary() {
|
|||
<div class="tile-content">
|
||||
<p class="tile-title text-bold">${escapeHtml(app.name)} ${versionInfo}</p>
|
||||
<p class="tile-subtitle">${escapeHtml(app.description)}${app.readme?`<br/>${readme}`:""}</p>
|
||||
<a href="https://github.com/espruino/BangleApps/tree/master/apps/${app.id}" target="_blank" class="link-github"><img src="img/github-icon-sml.png" alt="See the code on GitHub"/></a>
|
||||
<a href="${url}" target="_blank" class="link-github"><img src="img/github-icon-sml.png" alt="See the code on GitHub"/></a>
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-link btn-action btn-lg ${!app.custom?"text-error":"d-hide"}" appid="${app.id}" title="Favorite"><i class="icon"></i>${favourite?"♥":"♡"}</button>
|
||||
|
|
Loading…
Reference in New Issue