Skip to content

Commit f0ee2be

Browse files
authored
Merge pull request #3738 from WhelanB/clkshortcuts
New app "Shortcuts"
2 parents c517854 + e21979b commit f0ee2be

File tree

9 files changed

+298
-0
lines changed

9 files changed

+298
-0
lines changed

apps/clkshortcuts/ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.01: New app!

apps/clkshortcuts/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Shortcuts
2+
3+
An app that allows you to create custom ClockInfos that act as shortcuts to your favourite apps.
4+
5+
## Create a Shortcut
6+
After installing the app, you can open the app to add and manage existing shortcuts. If no shortcuts exist, the app will display a ``[+] Shortcuts`` button as a ClockInfo on your Clock (see screenshots), which when clicked will quickly launch into the app so you can add new shortcuts.
7+
8+
When adding a shortcut, first select the app you wish to use, then select the icon you wish to register to the shortcut. If a keyboard is installed, you'll get the option to rename the shortcut before saving.
9+
10+
Once created, your shortcut will appear on any Clocks with ClockInfo support, and tapping the shortcut will launch the chosen app
471 Bytes
Loading

apps/clkshortcuts/app-icon.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/clkshortcuts/app.js

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
var storage = require("Storage");
2+
var keyboard = "textinput";
3+
try {
4+
keyboard = require(keyboard);
5+
} catch (e) {
6+
keyboard = null;
7+
}
8+
9+
var icons = [
10+
{name:"agenda", img :"GBiBAAAAAAA8AAB+AA/n8B/n+BgAGBgAGBn/mBn/mBgAGBgAGBn/mBn/+BgD/BgHDhn+Bhn8MxgMIxgMIx/8Ew/+BgAHDgAD/AAA8A=="},
11+
{name:"alarm", img:"GBiBAAAAAAAAAAYAYA4AcBx+ODn/nAOBwAcA4A4YcAwYMBgYGBgYGBgYGBgYGBgeGBgHGAwBMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="},
12+
{name:"mail", img:"GBiBAAAAAAAAAAAAAAAAAB//+D///DAADDgAHDwAPDcA7DPDzDDnDDA8DDAYDDAADDAADDAADDAADD///B//+AAAAAAAAAAAAAAAAA=="},
13+
{name:"android", img: "GBiBAAAAAAEAgAD/AAD/AAHDgAGBgAMkwAMAwAP/wBv/2BsA2BsA2BsA2BsA2BsA2BsA2Bv/2AP/wADnAADnAADnAADnAADnAAAAAA=="},
14+
{name:"add", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgYGBgYGBgYGBgYGBn/mBn/mBgYGBgYGBgYGBgYGBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
15+
{name:"bangle", img:"GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA=="},
16+
{name:"bike", img:"GBiBAAAAAAAAAAAAAAAD+AAD/AADjAABjAfhnAfjyAMDwAcGwB4O+H8M/GGZ5sD7c8fzM8fjM8DDA2GBhn8B/h4AeAAAAAAAAAAAAA=="},
17+
{name:"map", img:"GBiBAAAAAAAAAAAAAADgGAf8+B//+BjHGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjjGB//+B8/4BgHAAAAAAAAAAAAAA=="},
18+
{name:"play", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBjAGBjwGBj8GBjeGBjHmBjB2BjB2BjHmBjeGBj8GBjwGBjAGBgAGB//+A//8AAAAAAAAAAAAA=="},
19+
{name:"fast forward", img:"GBiBAAAAAAAAAAAAAH///v///8AAA8YYA8eeA8f/g8b7w8Y488YYO8YYO8Y488b7w8f/g8eeA8YYA8AAA////3///gAAAAAAAAAAAA=="},
20+
{name:"rewind", img:"GBiBAAAAAAAAAAAAAH///v///8AAA8AYY8B548H/48PfY88cY9wYY9wYY88cY8PfY8H/48B548AYY8AAA////3///gAAAAAAAAAAAA=="},
21+
{name:"timer", img:"GBiBAAAAAAB+AAB+AAAAMAB+OAH/nAOByAcA4A4YcAwYMBgYGBgYGBgYGBgYGBgAGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="},
22+
{name:"connected", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBngGBn4GBgcGBgOGBnHGBnzGBgxmBgZmBmZmBmZmBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
23+
{name:"lock", img:"GBiBAAAAAAA8AAD/AAHDgAGBgAMAwAMAwAMAwAf/4A//8AwAMAwAMAwAMAwYMAw8MAw8MAwYMAwAMAwAMAwAMA//8Af/4AAAAAAAAA=="},
24+
{name:"battery", img:"GBiBAAAAAAAAAAB+AAB+AAHngAPnwAMAwAMAwAMIwAMIwAMYwAM4wAM+wAN8wAMcwAMYwAMQwAMQwAMAwAMAwAP/wAH/gAAAAAAAAA=="},
25+
{name:"game", img:"GBiBAAAAAAAAAAAAAAA8AAB+AABmAABmAAB+AAA8AAAYAAAYAAAYAAMYAA//8B//+BgAGBgAGBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
26+
{name:"dice", img:"GBiBAAAAAB//8D//+HAAPGMDHmeHnmeHnmMDHmAAHmMDHmeHnmeHnmMDHmAAHmMDHmeHnmeHnmMDHnAAPn///j///h///g///AAAAA=="},
27+
{name:"gear", img:"GBiBAAAAAAAAAAA8AAB+AABmAA3nsA/D8B8A+Dg8HBx+OAznMAzDMAzDMAznMBx+ODg8HB8A+A/D8A3nsABmAAB+AAA8AAAAAAAAAA=="},
28+
{name:"wrench", img:"GBiBAAAAAAAAAAAAAAAHgAAfwAA7gAAzEABjOABj+ABh+ABgGADgMAHAcAOP4AcfgA44AB9wADHgADHAADGAAB8AAA4AAAAAAAAAAA=="},
29+
{name:"calendar", img:"FhgBDADAMAMP/////////////////////8AADwAAPAAA8AADwAAPAAA8AADwAAPAAA8AADwAAPAAA8AADwAAP///////"},
30+
{name:"power", img:"GBiBAAAAAAAAAAB+AAH/gAeBwA4YcAwYMBjbGBnbmDGZjDMYzDMYzDMAzDMAzDGBjBnDmBj/GAw8MA4AcAeB4AH/gAB+AAAAAAAAAA=="},
31+
{name:"terminal", img:"GBiBAAAAAAAAAAAAAA//8B//+B//+B//+B//+BgAGBgAGBgAGBmAGBjAGBhgGBhgGBjAGBmPmBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
32+
{name:"camera", img:"GBiBAAAAAAAAAAD/AAH/gAMAwD8A/H8A/mA8BmD/BmHDhmGBhmMAxmMAxmMAxmMAxmGBhmHDhmD/BmA8BmAABn///j///AAAAAAAAA=="},
33+
{name:"phone", img:"GBiBAAAAAAAAAAOAAA/AABzgADBgADBgADBgABjgABjAABzAAAxgAA5wAAc58AMf+AGHHADgDABwDAA8GAAfGAAH8AAA4AAAAAAAAA=="},
34+
{name:"two prong plug", img:"GBiBAAABgAADwAAHwAAPgACfAAHOAAPkBgHwDwP4Hwf8Pg/+fB//OD//kD//wD//4D//8D//4B//QB/+AD/8AH/4APnwAHAAACAAAA=="},
35+
{name:"steps", img:"GBiBAAcAAA+AAA/AAA/AAB/AAB/gAA/g4A/h8A/j8A/D8A/D+AfH+AAH8AHn8APj8APj8AHj4AHg4AADAAAHwAAHwAAHgAAHgAADAA=="},
36+
{name:"graph", img:"GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA=="},
37+
{name:"hills", img:"GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA=="},
38+
{name:"sun", img:"GBiBAAAYAAAYAAAYAAgAEBwAOAx+MAD/AAHDgAMAwAcA4AYAYOYAZ+YAZwYAYAcA4AMAwAHDgAD/AAx+MBwAOAgAEAAYAAAYAAAYAA=="},
39+
{name:"home", img:"GBiBAAAAAAAAAAAAAAH/gAP/wAdg4A5wYA44MBwf+DgP/BgAGBgAGBgAGBnnmBnnmBnnmBnnmBngGBngGB//+B//+AAAAAAAAAAAAA=="},
40+
{name:"bell", img:"GBiBAAAAAAAAAAAfgAB/2ADw+AHAMAOAGAcAGD4ADHgADDgADBwADA4AHAcAGAOAOAHAcAPg4ANxwAM5gAP/AAHvAAAHAAACAAAAAA=="},
41+
{name:"bin", img:"GBiBAAAAAAAAAAB+AB//+B//+AwAMAwAMAxmMAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYANmwAMAwAMAwAP/wAH/gAAAAAAAAA=="},
42+
];
43+
44+
let storedApps;
45+
var showMainMenu = () => {
46+
storedApps = storage.readJSON("clkshortcuts.json", 1) || {};
47+
48+
var mainMenu = {
49+
"": {
50+
title: "Shortcuts",
51+
},
52+
"< Back": () => {
53+
load();
54+
},
55+
"New": () => {
56+
// Select the app
57+
getSelectedApp().then((app) => {
58+
getSelectedIcon().then((icon) => {
59+
promptForRename(app.name).then((name) => {
60+
E.showMessage("Saving...");
61+
storedApps[app.src] = {
62+
name: name, src: app.src, icon: icon
63+
};
64+
storage.writeJSON("clkshortcuts.json", storedApps);
65+
showMainMenu();
66+
}).catch(() => {
67+
E.showMessage("Saving...");
68+
storedApps[app.src] = {
69+
name: app.name, src: app.src, icon: icon
70+
};
71+
storage.writeJSON("clkshortcuts.json", storedApps);
72+
showMainMenu();
73+
} );
74+
}).catch(() => {showMainMenu();});
75+
}).catch(() => {showMainMenu();});
76+
},
77+
};
78+
getStoredAppsArray(storedApps).forEach((app) => {
79+
mainMenu[app.name] = {
80+
onchange: () => {
81+
showEditMenu(app).then((dirty) => {
82+
if (dirty) {
83+
E.showMessage("Saving...");
84+
storage.writeJSON("clkshortcuts.json", storedApps);
85+
}
86+
showMainMenu();
87+
});
88+
},
89+
format: v=>"\0" + atob(app.icon)
90+
};
91+
});
92+
E.showMenu(mainMenu);
93+
};
94+
95+
var showEditMenu = (app) => {
96+
return new Promise((resolve, reject) => {
97+
var editMenu = {
98+
"": {
99+
title: "Edit " + app.name,
100+
},
101+
"< Back": () => {
102+
resolve(false);
103+
},
104+
"Name":{
105+
onchange: () => {
106+
promptForRename(app.name).then((name) => {
107+
storedApps[app.src].name = name;
108+
resolve(true);
109+
}).catch();
110+
},
111+
format: v=>app.name.substring(0, 7)
112+
},
113+
"Icon": {
114+
onchange: () => {
115+
getSelectedIcon().then((icon) => {
116+
storedApps[app.src].icon = icon;
117+
resolve(true);
118+
}).catch(() => resolve(false));
119+
},
120+
format: v=>"\0" + atob(app.icon)
121+
},
122+
"Delete": {
123+
onchange: () => {
124+
delete storedApps[app.src]
125+
resolve(true);
126+
},
127+
format: v=>"\0" + atob("GBiBAAAAAAAAAAB+AB//+B//+AwAMAwAMAxmMAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYANmwAMAwAMAwAP/wAH/gAAAAAAAAA==")
128+
}
129+
};
130+
E.showMenu(editMenu);
131+
});
132+
};
133+
134+
var promptForRename = (name) => {
135+
return new Promise((resolve, reject) => {
136+
if (!keyboard) { reject("No textinput is available"); }
137+
else {
138+
return require("textinput").input({text:name}).then((result) => resolve(result));
139+
}
140+
});
141+
};
142+
143+
var getStoredAppsArray = (apps) => {
144+
var appList = Object.keys(apps);
145+
var storedAppArray = [];
146+
for (var i = 0; i < appList.length; i++) {
147+
var app = "" + appList[i];
148+
storedAppArray.push(
149+
apps[app]
150+
);
151+
}
152+
return storedAppArray;
153+
};
154+
155+
var getSelectedIcon = () => {
156+
return new Promise((resolve, reject) => {
157+
var iconMenu = {
158+
"": {
159+
title: "Select Icon",
160+
},
161+
"< Back": () => {
162+
reject("The user cancelled the operation");
163+
},
164+
};
165+
166+
icons.forEach((icon) => {
167+
iconMenu["\0" + atob(icon.img) + " " + icon.name] = () => {
168+
resolve(icon.img);
169+
};
170+
});
171+
172+
E.showMenu(iconMenu);
173+
});
174+
};
175+
176+
var getAppList = () => {
177+
var appList = storage
178+
.list(/\.info$/)
179+
.map((appInfoFileName) => {
180+
var appInfo = storage.readJSON(appInfoFileName, 1);
181+
return (
182+
appInfo && {
183+
name: appInfo.name,
184+
sortorder: appInfo.sortorder,
185+
src: appInfo.src,
186+
}
187+
);
188+
})
189+
.filter((app) => app && !!app.src);
190+
appList.sort((a, b) => {
191+
var n = (0 | a.sortorder) - (0 | b.sortorder);
192+
if (n) return n;
193+
if (a.name < b.name) return -1;
194+
if (a.name > b.name) return 1;
195+
return 0;
196+
});
197+
198+
return appList;
199+
};
200+
201+
var getSelectedApp = () => {
202+
return new Promise((resolve, reject) => {
203+
E.showMessage("Loading apps...");
204+
var selectAppMenu = {
205+
"": {
206+
title: "Select App",
207+
},
208+
"< Back": () => {
209+
reject("The user cancelled the operation");
210+
},
211+
};
212+
213+
var appList = getAppList();
214+
appList.forEach((app) => {
215+
selectAppMenu[app.name] = () => {
216+
resolve(app);
217+
};
218+
});
219+
220+
E.showMenu(selectAppMenu);
221+
});
222+
};
223+
224+
showMainMenu();

apps/clkshortcuts/app.png

1.1 KB
Loading

apps/clkshortcuts/clkinfo.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
(function() {
2+
var storage = require("Storage");
3+
var storedApps = storage.readJSON("clkshortcuts.json", 1) || {};
4+
var items = [];
5+
if (Object.keys(storedApps).length !== 0) {
6+
for (var key in storedApps) {
7+
var source = {
8+
name: storedApps[key].name,
9+
img: storedApps[key].icon,
10+
src: storedApps[key].src,
11+
get : function() {
12+
return {
13+
text : this.name,
14+
img : atob(this.img)
15+
}
16+
},
17+
run: function() { load(this.src);},
18+
show : function() {},
19+
hide : function() {},
20+
}
21+
items.push(source);
22+
}
23+
}
24+
else {
25+
var source = {
26+
name: "Shortcuts",
27+
img: "GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgYGBgYGBgYGBgYGBn/mBn/mBgYGBgYGBgYGBgYGBgAGBgAGB//+A//8AAAAAAAAAAAAA==",
28+
src: "clkshortcuts.app.js",
29+
get : function() {
30+
return {
31+
text : this.name,
32+
img : atob(this.img)
33+
}
34+
},
35+
run: function() { load(this.src);},
36+
show : function() {},
37+
hide : function() {},
38+
};
39+
items = [source];
40+
}
41+
return {
42+
name: "Shortcuts",
43+
items: items
44+
};
45+
})
622 Bytes
Loading

apps/clkshortcuts/metadata.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{ "id": "clkshortcuts",
2+
"name": "Shortcuts",
3+
"shortName": "Shortcuts",
4+
"version": "0.01",
5+
"description": "Add shortcuts to launch your favourite apps straight from the Clock",
6+
"icon": "app.png",
7+
"screenshots": [{"url":"add_shortcuts_screenshot.png"}, {"url":"example_shortcuts_screenshot.png"}],
8+
"tags": "clkinfo,clockinfo",
9+
"supports": ["BANGLEJS2"],
10+
"readme": "README.md",
11+
"storage": [
12+
{ "name": "clkshortcuts.app.js", "url": "app.js" },
13+
{ "name": "clkshortcuts.img", "url": "app-icon.js", "evaluate": true },
14+
{"name":"clkshortcuts.clkinfo.js","url":"clkinfo.js"}
15+
],
16+
"data": [{"name":"clkshortcuts.json"}]
17+
}

0 commit comments

Comments
 (0)