diff --git a/README.md b/README.md index 1058787bb..fed13a358 100644 --- a/README.md +++ b/README.md @@ -282,8 +282,11 @@ and which gives information about the app for the Launcher. "dependencies" : { "notify":"type" } // optional, app 'types' we depend on (see "type" above) "dependencies" : { "messages":"app" } // optional, depend on a specific app ID // for instance this will use notify/notifyfs is they exist, or will pull in 'notify' - "dependencies" : { "messageicons":"module" } // optional, depend on a specific library to be used with 'require' + "dependencies" : { "messageicons":"module" } // optional, depend on a specific library to be used with 'require' - see provides_modules + "dependencies" : { "message":"widget" } // optional, depend on a specific type of widget - see provides_widgets "provides_modules" : ["messageicons"] // optional, this app provides a module that can be used with 'require' + "provides_widgets" : ["battery"] // optional, this app provides a type of widget - 'alarm/battery/bluetooth/pedometer/message' + "default" : true, // set if an app is the default implementer of something (a widget/module/etc) "readme": "README.md", // if supplied, a link to a markdown-style text file // that contains more information about this app (usage, etc) // A 'Read more...' link will be added under the app diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog index 6ce6147ca..9994d33d9 100644 --- a/apps/alarm/ChangeLog +++ b/apps/alarm/ChangeLog @@ -36,4 +36,4 @@ 0.33: Allow hiding timers&alarms 0.34: Add "Confirm" option to alarm/timer edit menus 0.35: Add automatic translation of more strings - +0.36: alarm widget moved out of app diff --git a/apps/alarm/metadata.json b/apps/alarm/metadata.json index a02985851..dbf090774 100644 --- a/apps/alarm/metadata.json +++ b/apps/alarm/metadata.json @@ -2,17 +2,16 @@ "id": "alarm", "name": "Alarms & Timers", "shortName": "Alarms", - "version": "0.35", + "version": "0.36", "description": "Set alarms and timers on your Bangle", "icon": "app.png", - "tags": "tool,alarm,widget", + "tags": "tool,alarm", "supports": [ "BANGLEJS", "BANGLEJS2" ], "readme": "README.md", - "dependencies": { "scheduler":"type" }, + "dependencies": { "scheduler":"type", "alarm":"widget" }, "storage": [ { "name": "alarm.app.js", "url": "app.js" }, - { "name": "alarm.img", "url": "app-icon.js", "evaluate": true }, - { "name": "alarm.wid.js", "url": "widget.js" } + { "name": "alarm.img", "url": "app-icon.js", "evaluate": true } ], "screenshots": [ { "url": "screenshot-1.png" }, diff --git a/apps/gallery/ChangeLog b/apps/gallery/ChangeLog index 76db22053..0167bc1f9 100644 --- a/apps/gallery/ChangeLog +++ b/apps/gallery/ChangeLog @@ -1,2 +1,3 @@ 0.01: New app! -0.02: Submitted to app loader \ No newline at end of file +0.02: Submitted to app loader +0.03: Do not invert colors diff --git a/apps/gallery/app.js b/apps/gallery/app.js index ca9392f13..6fb2bdf49 100644 --- a/apps/gallery/app.js +++ b/apps/gallery/app.js @@ -35,7 +35,7 @@ function drawImage(fileName) { Bangle.setLCDBrightness(1); // Full brightness image = eval(storage.read(fileName)); // Sadly, the only reasonable way to do this - g.clear().reset().drawImage(image, 88, 88, { rotate: angle }); + g.clear().reset().setBgColor(0).setColor("#fff").drawImage(image, 88, 88, { rotate: angle }); } setWatch(info => { @@ -44,9 +44,9 @@ setWatch(info => { else angle = 0; Bangle.buzz(); - g.clear().reset().drawImage(image, 88, 88, { rotate: angle }) + g.clear().reset().setBgColor(0).setColor("#fff").drawImage(image, 88, 88, { rotate: angle }) } }, BTN1, { repeat: true }); // We don't load the widgets because there is no reasonable way to unload them -drawMenu(); \ No newline at end of file +drawMenu(); diff --git a/apps/gallery/metadata.json b/apps/gallery/metadata.json index 0dc8d1613..00ac42075 100644 --- a/apps/gallery/metadata.json +++ b/apps/gallery/metadata.json @@ -1,7 +1,7 @@ { "id": "gallery", "name": "Gallery", - "version": "0.02", + "version": "0.03", "description": "A gallery that lets you view images uploaded with the IDE (see README)", "readme": "README.md", "icon": "icon.png", diff --git a/apps/launch/metadata.json b/apps/launch/metadata.json index 4d0270e37..85fcdd02f 100644 --- a/apps/launch/metadata.json +++ b/apps/launch/metadata.json @@ -7,6 +7,7 @@ "readme": "README.md", "icon": "app.png", "type": "launch", + "default": true, "tags": "tool,system,launcher", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ diff --git a/apps/messagegui/metadata.json b/apps/messagegui/metadata.json index b3e70d5d4..f3798f645 100644 --- a/apps/messagegui/metadata.json +++ b/apps/messagegui/metadata.json @@ -9,6 +9,7 @@ "supports": ["BANGLEJS","BANGLEJS2"], "dependencies" : { "messageicons":"module" }, "provides_modules": ["messagegui"], + "default": true, "readme": "README.md", "storage": [ {"name":"messagegui","url":"lib.js"}, diff --git a/apps/messageicons/metadata.json b/apps/messageicons/metadata.json index b6ce34f88..b621c55b9 100644 --- a/apps/messageicons/metadata.json +++ b/apps/messageicons/metadata.json @@ -8,6 +8,7 @@ "tags": "tool,system", "supports": ["BANGLEJS","BANGLEJS2"], "provides_modules" : ["messageicons"], + "default": true, "storage": [ {"name":"messageicons","url":"lib.js"} ] diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index 8bcf3da25..27e771975 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -8,7 +8,11 @@ "tags": "tool,system", "supports": ["BANGLEJS","BANGLEJS2"], "provides_modules" : ["messages"], - "dependencies" : { "messagegui":"module","messagewidget":"module" }, + "dependencies" : { + "messagegui":"module", + "message":"widget" + }, + "default": true, "readme": "README.md", "storage": [ {"name":"messages","url":"lib.js"}, diff --git a/apps/noteify/ChangeLog b/apps/noteify/ChangeLog index d7bc46dcd..a37a66731 100644 --- a/apps/noteify/ChangeLog +++ b/apps/noteify/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial version 0.02: Use default Bangle formatter for booleans +0.03: Drop duplicate alarm widget diff --git a/apps/noteify/metadata.json b/apps/noteify/metadata.json index fbd5a88f1..850628c46 100644 --- a/apps/noteify/metadata.json +++ b/apps/noteify/metadata.json @@ -1,7 +1,7 @@ { "id": "noteify", "name": "Noteify", - "version": "0.02", + "version": "0.03", "description": "Write notes using an onscreen keyboard and use them as custom messages for alarms or timers.", "icon": "app.png", "tags": "tool,alarm", @@ -9,8 +9,7 @@ "readme": "README.md", "storage": [ {"name":"noteify.app.js","url":"app.js"}, - {"name":"noteify.img","url":"app-icon.js","evaluate":true}, - {"name":"noteify.wid.js","url":"widget.js"} + {"name":"noteify.img","url":"app-icon.js","evaluate":true} ], "data": [{"name":"noteify.json"}], "dependencies": {"scheduler":"type","textinput":"type"}, diff --git a/apps/noteify/widget.js b/apps/noteify/widget.js deleted file mode 100644 index 052ac9ebd..000000000 --- a/apps/noteify/widget.js +++ /dev/null @@ -1,8 +0,0 @@ -WIDGETS["alarm"]={area:"tl",width:0,draw:function() { - if (this.width) g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y); - },reload:function() { - // don't include library here as we're trying to use as little RAM as possible - WIDGETS["alarm"].width = (require('Storage').readJSON('sched.json',1)||[]).some(alarm=>alarm.on&&(alarm.hidden!==false)) ? 24 : 0; - } -}; -WIDGETS["alarm"].reload(); diff --git a/apps/podadrem/ChangeLog b/apps/podadrem/ChangeLog index c26e40c0e..3c68f15ac 100644 --- a/apps/podadrem/ChangeLog +++ b/apps/podadrem/ChangeLog @@ -4,3 +4,6 @@ Addict. 0.04: New layout. 0.05: Add widget field, tweak layout. +0.06: Add compatibility with Fastload Utils. +0.07: Remove just the specific listeners to not interfere with Quick Launch +when fastloading. diff --git a/apps/podadrem/app.js b/apps/podadrem/app.js index b04d80b17..9c9ed8b04 100644 --- a/apps/podadrem/app.js +++ b/apps/podadrem/app.js @@ -1,77 +1,20 @@ +{ /* -Bluetooth.println(JSON.stringify({t:"intent", action:"", flags:["flag1", "flag2",...], categories:["category1","category2",...], mimetype:"", data:"", package:"", class:"", target:"", extra:{someKey:"someValueOrString"}})); + Bluetooth.println(JSON.stringify({t:"intent", action:"", flags:["flag1", "flag2",...], categories:["category1","category2",...], mimetype:"", data:"", package:"", class:"", target:"", extra:{someKey:"someValueOrString"}})); -Podcast Addict is developed by Xavier Guillemane and can be downloaded on Google Play Store: https://play.google.com/store/apps/details?id=com.bambuna.podcastaddict&hl=en_US&gl=US - -Podcast Addict can be controlled through the sending of remote commands called 'Intents'. -Some 3rd parties apps specialized in task automation will then allow you to control Podcast Addict. For example, you will be able to wake up to the sound of your playlist or to start automatically playing when some NFC tag has been detected. -In Tasker, you just need to copy/paste one of the following intent in the task Action field ("Misc" action type then select "Send Itent") . -If you prefer Automate It, you can use the Podcast Addict plugin that will save you some configuration time (https://play.google.com/store/apps/details?id=com.smarterapps.podcastaddictplugin ) -Before using an intent make sure to set the following: -Package: com.bambuna.podcastaddict -Class (UPDATE intent only): com.bambuna.podcastaddict.receiver.PodcastAddictBroadcastReceiver -Class (every other intent): com.bambuna.podcastaddict.receiver.PodcastAddictPlayerReceiver -Here are the supported commands (Intents) : -com.bambuna.podcastaddict.service.player.toggle – Toggle the playlist -com.bambuna.podcastaddict.service.player.stop – Stop the player and release its resources -com.bambuna.podcastaddict.service.player.play – Start playing the playlist -com.bambuna.podcastaddict.service.player.pause – Pause the playlist -com.bambuna.podcastaddict.service.player.nexttrack – Start playing next track -com.bambuna.podcastaddict.service.player.previoustrack – Start playing previous track -com.bambuna.podcastaddict.service.player.jumpforward – Jump 30s forward -com.bambuna.podcastaddict.service.player.jumpbackward – Jump 15s backward -com.bambuna.podcastaddict.service.player.1xspeed - Disable the variable playback speed -com.bambuna.podcastaddict.service.player.1.5xspeed – Force the playback speed at 1.5x -com.bambuna.podcastaddict.service.player.2xspeed – Force the playback speed at 2.0x -com.bambuna.podcastaddict.service.player.stoptimer – Disable the timer -com.bambuna.podcastaddict.service.player.15mntimer – Set the timer at 15 minutes -com.bambuna.podcastaddict.service.player.30mntimer – Set the timer at 30 minutes -com.bambuna.podcastaddict.service.player.60mntimer – Set the timer at 1 hour -com.bambuna.podcastaddict.service.update – Trigger podcasts update -com.bambuna.podcastaddict.openmainscreen – Open the app on the Main screen -com.bambuna.podcastaddict.openplaylist – Open the app on the Playlist screen -com.bambuna.podcastaddict.openplayer – Open the app on the Player screen -com.bambuna.podcastaddict.opennewepisodes – Open the app on the New episodes screen -com.bambuna.podcastaddict.opendownloadedepisodes – Open the app on the Downloaded episodes screen -com.bambuna.podcastaddict.service.player.playfirstepisode – Start playing the first episode in the playlist -com.bambuna.podcastaddict.service.player.customspeed – Select playback speed -In order to use this intent you need to pass a float argument called "arg1". Valid values are within [0.1, 5.0] -com.bambuna.podcastaddict.service.player.customtimer – Start a custom timer -In order to use this intent you need to pass an int argument called "arg1" containing the number of minutes. Valid values are within [1, 1440] -com.bambuna.podcastaddict.service.player.deletecurrentskipnexttrack – Delete the current episode and skip to the next one. It behaves the same way as long pressing on the player >| button, but doesn't display any confirmation popup. -com.bambuna.podcastaddict.service.player.deletecurrentskipprevioustrack – Delete the current episode and skip to the previous one. It behaves the same way as long pressing on the player |< button, but doesn't display any confirmation popup. -com.bambuna.podcastaddict.service.player.boostVolume – Toggle the Volume Boost audio effect -You can pass a, optional boolean argument called "arg1" in order to create a ON or OFF button for the volume boost. Without this parameter the app will just toggle the current value -com.bambuna.podcastaddict.service.player.quickBookmark – Creates a bookmark at the current playback position so you can easily retrieve it later. -com.bambuna.podcastaddict.service.download.pause – Pause downloads -com.bambuna.podcastaddict.service.download.resume – Resume downloads -com.bambuna.podcastaddict.service. download.toggle – Toggle downloads -com.bambuna.podcastaddict.service.player.favorite – Mark the current episode playing as favorite. -com.bambuna.podcastaddict.openplaylist – Open the app on the Playlist screen -You can pass an optional string argument called "arg1" in order to select the playlist to open. Without this parameter the app will open the current playlist -Here's how it works: -##AUDIO## will open the Audio playlist screen -##VIDEO## will open the Video playlist screen -##RADIO## will open the Radio screen -Any other argument will be used as a CATEGORY name. The app will then open this category under the playlist CUSTOM tab -You can pass an optional boolean argument called "arg2" in order to select if the app UI should be opened. Without this parameter the playlist will be displayed -You can pass an optional boolean argument called "arg3" in order to select if the app should start playing the selected playlist. Without this parameter the playback won't start -Since v2020.3 -com.bambuna.podcastaddict.service.full_backup – Trigger a full backup of the app data (relies on the app automatic backup settings for the folder and the # of backup to keep) -This task takes a lot of resources and might take up to a minute to complete, so please avoid using the app at the same time -Since v2020.15 -com.bambuna.podcastaddict.service.player.toggletimer – This will toggle the Sleep Timer using the last duration and parameter used in the app. -Since v2020.16 -com.bambuna.podcastaddict.service.player.togglespeed – This will toggle the Playback speed for the episode currently playing (alternate between selected speed and 1.0x). + Podcast Addict is developed by Xavier Guillemane and can be downloaded on Google Play Store: https://play.google.com/store/apps/details?id=com.bambuna.podcastaddict&hl=en_US&gl=US + + How to use intents to control Podcast Addict: https://podcastaddict.com/faq/130 */ -var R; -var backToMenu = false; -var dark = g.theme.dark; // bool +let R; +let widgetUtils = require("widget_utils"); +let backToMenu = false; +let dark = g.theme.dark; // bool // The main layout of the app -function gfx() { - //Bangle.drawWidgets(); +let gfx = function() { + widgetUtils.hide(); R = Bangle.appRect; marigin = 8; // g.drawString(str, x, y, solid) @@ -106,19 +49,19 @@ function gfx() { g.setFontAlign(1, 1, 0); g.drawString("Speed", R.x + R.w - 2*marigin, R.y + R.h - 2*marigin); -} +}; // Touch handler for main layout -function touchHandler(_, xy) { +let touchHandler = function(_, xy) { x = xy.x; y = xy.y; len = (R.wb-1 instead of a>b. + // doing ab-1 instead of a>=b. if ((R.x-1 { - if (ud) Bangle.musicControl(ud>0 ? "volumedown" : "volumeup"); - } + {mode : "updown", + remove : ()=>{ + Bangle.removeListener("touch", touchHandler); + Bangle.removeListener("swipe", swipeHandler); + clearWatch(buttonHandler); + widgetUtils.show(); + } + }, + ud => { + if (ud) Bangle.musicControl(ud>0 ? "volumedown" : "volumeup"); + } ); Bangle.on("touch", touchHandler); Bangle.on("swipe", swipeHandler); -} + let buttonHandler = setWatch(()=>{load();}, BTN, {edge:'falling'}); +}; /* The functions for interacting with Android and the Podcast Addict app */ -pkg = "com.bambuna.podcastaddict"; -standardCls = pkg + ".receiver.PodcastAddictPlayerReceiver"; -updateCls = pkg + ".receiver.PodcastAddictBroadcastReceiver"; -speed = 1.0; +let pkg = "com.bambuna.podcastaddict"; +let standardCls = pkg + ".receiver.PodcastAddictPlayerReceiver"; +let updateCls = pkg + ".receiver.PodcastAddictBroadcastReceiver"; +let speed = 1.0; -simpleSearch = ""; +let simpleSearch = ""; -function simpleSearchTerm() { // input a simple search term without tags, overrides search with tags (artist and track) +let simpleSearchTerm = function() { // input a simple search term without tags, overrides search with tags (artist and track) require("textinput").input({ text: simpleSearch }).then(result => { @@ -189,9 +140,9 @@ function simpleSearchTerm() { // input a simple search term without tags, overri }).then(() => { E.showMenu(searchMenu); }); -} +}; -function searchPlayWOTags() { //make a search and play using entered terms +let searchPlayWOTags = function() { //make a search and play using entered terms searchString = simpleSearch; Bluetooth.println(JSON.stringify({ t: "intent", @@ -203,9 +154,9 @@ function searchPlayWOTags() { //make a search and play using entered terms }, flags: ["FLAG_ACTIVITY_NEW_TASK"] })); -} +}; -function gadgetbridgeWake() { +let gadgetbridgeWake = function() { Bluetooth.println(JSON.stringify({ t: "intent", target: "activity", @@ -213,15 +164,15 @@ function gadgetbridgeWake() { package: "gadgetbridge", class: "nodomain.freeyourgadget.gadgetbridge.activities.WakeActivity" })); -} +}; // For stringing together the action for Podcast Addict to perform -function actFn(actName, activOrServ) { +let actFn = function(actName, activOrServ) { return "com.bambuna.podcastaddict." + (activOrServ == "service" ? "service." : "") + actName; -} +}; // Send the intent message to Gadgetbridge -function btMsg(activOrServ, cls, actName, xtra) { +let btMsg = function(activOrServ, cls, actName, xtra) { Bluetooth.println(JSON.stringify({ t: "intent", @@ -231,22 +182,20 @@ function btMsg(activOrServ, cls, actName, xtra) { target: "broadcastreceiver", extra: xtra })); -} +}; // Get back to the main layout -function backToGfx() { +let backToGfx = function() { E.showMenu(); g.clear(); g.reset(); - Bangle.removeAllListeners("touch"); - Bangle.removeAllListeners("swipe"); setUI(); gfx(); backToMenu = false; -} +}; // Podcast Addict Menu -var paMenu = { +let paMenu = { "": { title: " ", back: backToGfx @@ -271,7 +220,7 @@ var paMenu = { }; -var controlMenu = { +let controlMenu = { "": { title: " ", back: () => {if (backToMenu) E.showMenu(paMenu); @@ -310,7 +259,7 @@ var controlMenu = { }, }; -var speedMenu = { +let speedMenu = { "": { title: " ", back: () => {if (backToMenu) E.showMenu(paMenu); @@ -333,7 +282,7 @@ var speedMenu = { //"Slower" : ()=>{speed-=0.1; speed=((speed<0.1)?0.1:speed); btMsg("service",standardCls,"player.customspeed",{arg1:speed});}, }; -var searchMenu = { +let searchMenu = { "": { title: " ", @@ -356,7 +305,7 @@ var searchMenu = { "Simpler search and play" : searchPlayWOTags, }; -var navigationMenu = { +let navigationMenu = { "": { title: " ", back: () => {if (backToMenu) E.showMenu(paMenu); @@ -372,4 +321,6 @@ var navigationMenu = { Bangle.loadWidgets(); setUI(); +widgetUtils.hide(); gfx(); +} diff --git a/apps/podadrem/metadata.json b/apps/podadrem/metadata.json index 929269762..c58b9241d 100644 --- a/apps/podadrem/metadata.json +++ b/apps/podadrem/metadata.json @@ -2,7 +2,7 @@ "id": "podadrem", "name": "Podcast Addict Remote", "shortName": "PA Remote", - "version": "0.05", + "version": "0.07", "description": "Control Podcast Addict on your android device.", "readme": "README.md", "type": "app", diff --git a/apps/sched/metadata.json b/apps/sched/metadata.json index a457d0f44..a266d11f8 100644 --- a/apps/sched/metadata.json +++ b/apps/sched/metadata.json @@ -7,6 +7,8 @@ "type": "scheduler", "tags": "tool,system,alarm", "supports": ["BANGLEJS","BANGLEJS2"], + "provides_modules" : ["sched"], + "default" : true, "readme": "README.md", "storage": [ {"name":"sched.boot.js","url":"boot.js"}, diff --git a/apps/sleepphasealarm/ChangeLog b/apps/sleepphasealarm/ChangeLog index 80b2e554b..795c62fa2 100644 --- a/apps/sleepphasealarm/ChangeLog +++ b/apps/sleepphasealarm/ChangeLog @@ -12,3 +12,4 @@ Add setting to disable scheduler alarm 0.10: Fix: Do not wake when falling asleep 0.11: Minor tweaks +0.12: Support javascript command to execute as defined in scheduler 'js' configuration diff --git a/apps/sleepphasealarm/app.js b/apps/sleepphasealarm/app.js index a5193b244..ba8bff9b2 100644 --- a/apps/sleepphasealarm/app.js +++ b/apps/sleepphasealarm/app.js @@ -173,12 +173,16 @@ if (nextAlarmDate !== undefined) { setTimeout(load, 1000); } else if (measure && now >= minAlarm && swest === false) { addLog(now, "alarm"); - buzz(); measure = false; - if (config.settings.disableAlarm) { - // disable alarm for scheduler - nextAlarmConfig.last = now.getDate(); - require("Storage").writeJSON("sched.json", alarms); + if (nextAlarmConfig.js) { + eval(nextAlarmConfig.js); // run nextAlarmConfig.js if set + } else { + buzz(); + if (config.settings.disableAlarm) { + // disable alarm for scheduler + nextAlarmConfig.last = now.getDate(); + require('Storage').writeJSON('sched.json', alarms); + } } } }); diff --git a/apps/sleepphasealarm/metadata.json b/apps/sleepphasealarm/metadata.json index fd3366812..ced99062f 100644 --- a/apps/sleepphasealarm/metadata.json +++ b/apps/sleepphasealarm/metadata.json @@ -2,7 +2,7 @@ "id": "sleepphasealarm", "name": "SleepPhaseAlarm", "shortName": "SleepPhaseAlarm", - "version": "0.11", + "version": "0.12", "description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.", "icon": "app.png", "tags": "alarm", diff --git a/apps/spotrem/ChangeLog b/apps/spotrem/ChangeLog index 8e3d8b652..a92ed3de2 100644 --- a/apps/spotrem/ChangeLog +++ b/apps/spotrem/ChangeLog @@ -3,3 +3,6 @@ 0.03: change handling of intent extras. 0.04: New layout. 0.05: Add widgets field. Tweak layout. +0.06: Make compatible with Fastload Utils app. +0.07: Remove just the specific listeners to not interfere with Quick Launch +when fastloading. diff --git a/apps/spotrem/app.js b/apps/spotrem/app.js index 7e76d84bc..f9046c4a6 100644 --- a/apps/spotrem/app.js +++ b/apps/spotrem/app.js @@ -1,21 +1,23 @@ +{ /* Bluetooth.println(JSON.stringify({t:"intent", action:"", flags:["flag1", "flag2",...], categories:["category1","category2",...], mimetype:"", data:"", package:"", class:"", target:"", extra:{someKey:"someValueOrString"}})); */ -var R; -var backToMenu = false; -var isPaused = true; -var dark = g.theme.dark; // bool +let R; +let widgetUtils = require("widget_utils"); +let backToMenu = false; +let isPaused = true; +let dark = g.theme.dark; // bool // The main layout of the app -function gfx() { - //Bangle.drawWidgets(); +let gfx = function() { + widgetUtils.hide(); R = Bangle.appRect; marigin = 8; // g.drawString(str, x, y, solid) g.clearRect(R); g.reset(); - + if (dark) {g.setColor(0x07E0);} else {g.setColor(0x03E0);} // Green on dark theme, DarkGreen on light theme. g.setFont("4x6:2"); g.setFontAlign(1, 0, 0); @@ -44,10 +46,10 @@ function gfx() { g.setFontAlign(1, 1, 0); g.drawString("Saved", R.x + R.w - 2*marigin, R.y + R.h - 2*marigin); -} +}; // Touch handler for main layout -function touchHandler(_, xy) { +let touchHandler = function(_, xy) { x = xy.x; y = xy.y; len = (R.wb-1 instead of a>b. if ((R.x-1 { - if (ud) Bangle.musicControl(ud>0 ? "volumedown" : "volumeup"); - } + {mode : "updown", + remove : ()=>{ + Bangle.removeListener("touch", touchHandler); + Bangle.removeListener("swipe", swipeHandler); + clearWatch(buttonHandler); + widgetUtils.show(); + } + }, + ud => { + if (ud) Bangle.musicControl(ud>0 ? "volumedown" : "volumeup"); + } ); Bangle.on("touch", touchHandler); Bangle.on("swipe", swipeHandler); -} - - + let buttonHandler = setWatch(()=>{load();}, BTN, {edge:'falling'}); +}; // Get back to the main layout -function backToGfx() { +let backToGfx = function() { E.showMenu(); g.clear(); g.reset(); - Bangle.removeAllListeners("touch"); - Bangle.removeAllListeners("swipe"); setUI(); gfx(); backToMenu = false; -} +}; /* The functions for interacting with Android and the Spotify app */ simpleSearch = ""; -function simpleSearchTerm() { // input a simple search term without tags, overrides search with tags (artist and track) +let simpleSearchTerm = function() { // input a simple search term without tags, overrides search with tags (artist and track) require("textinput").input({text:simpleSearch}).then(result => {simpleSearch = result;}).then(() => {E.showMenu(searchMenu);}); -} +}; artist = ""; -function artistSearchTerm() { // input artist to search for +let artistSearchTerm = function() { // input artist to search for require("textinput").input({text:artist}).then(result => {artist = result;}).then(() => {E.showMenu(searchMenu);}); -} +}; track = ""; -function trackSearchTerm() { // input track to search for +let trackSearchTerm = function() { // input track to search for require("textinput").input({text:track}).then(result => {track = result;}).then(() => {E.showMenu(searchMenu);}); -} +}; album = ""; -function albumSearchTerm() { // input album to search for +let albumSearchTerm = function() { // input album to search for require("textinput").input({text:album}).then(result => {album = result;}).then(() => {E.showMenu(searchMenu);}); -} +}; -function searchPlayWOTags() {//make a spotify search and play using entered terms +let searchPlayWOTags = function() {//make a spotify search and play using entered terms searchString = simpleSearch; Bluetooth.println(JSON.stringify({t:"intent", action:"android.media.action.MEDIA_PLAY_FROM_SEARCH", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", target:"activity", extra:{query:searchString}, flags:["FLAG_ACTIVITY_NEW_TASK"]})); -} +}; -function searchPlayWTags() {//make a spotify search and play using entered terms +let searchPlayWTags = function() {//make a spotify search and play using entered terms searchString = (artist=="" ? "":("artist:\""+artist+"\"")) + ((artist!="" && track!="") ? " ":"") + (track=="" ? "":("track:\""+track+"\"")) + (((artist!="" && album!="") || (track!="" && album!="")) ? " ":"") + (album=="" ? "":(" album:\""+album+"\"")); Bluetooth.println(JSON.stringify({t:"intent", action:"android.media.action.MEDIA_PLAY_FROM_SEARCH", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", target:"activity", extra:{query:searchString}, flags:["FLAG_ACTIVITY_NEW_TASK"]})); -} +}; -function playVreden() {//Play the track "Vreden" by Sara Parkman via spotify uri-link +let playVreden = function() {//Play the track "Vreden" by Sara Parkman via spotify uri-link Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:track:5QEFFJ5tAeRlVquCUNpAJY:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function playVredenAlternate() {//Play the track "Vreden" by Sara Parkman via spotify uri-link +let playVredenAlternate = function() {//Play the track "Vreden" by Sara Parkman via spotify uri-link Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:track:5QEFFJ5tAeRlVquCUNpAJY:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK"]})); -} +}; -function searchPlayVreden() {//Play the track "Vreden" by Sara Parkman via search and play +let searchPlayVreden = function() {//Play the track "Vreden" by Sara Parkman via search and play Bluetooth.println(JSON.stringify({t:"intent", action:"android.media.action.MEDIA_PLAY_FROM_SEARCH", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", target:"activity", extra:{query:'artist:"Sara Parkman" track:"Vreden"'}, flags:["FLAG_ACTIVITY_NEW_TASK"]})); -} +}; -function openAlbum() {//Play EP "The Blue Room" by Coldplay +let openAlbum = function() {//Play EP "The Blue Room" by Coldplay Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:album:3MVb2CWB36x7VwYo5sZmf2", target:"activity", flags:["FLAG_ACTIVITY_NEW_TASK"]})); -} +}; -function searchPlayAlbum() {//Play EP "The Blue Room" by Coldplay via search and play +let searchPlayAlbum = function() {//Play EP "The Blue Room" by Coldplay via search and play Bluetooth.println(JSON.stringify({t:"intent", action:"android.media.action.MEDIA_PLAY_FROM_SEARCH", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", target:"activity", extra:{query:'album:"The blue room" artist:"Coldplay"', "android.intent.extra.focus":"vnd.android.cursor.item/album"}, flags:["FLAG_ACTIVITY_NEW_TASK"]})); -} +}; -function spotifyWidget(action) { +let spotifyWidget = function(action) { Bluetooth.println(JSON.stringify({t:"intent", action:("com.spotify.mobile.android.ui.widget."+action), package:"com.spotify.music", target:"broadcastreceiver"})); -} +}; -function gadgetbridgeWake() { +let gadgetbridgeWake = function() { Bluetooth.println(JSON.stringify({t:"intent", target:"activity", flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_CLEAR_TASK", "FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS", "FLAG_ACTIVITY_NO_ANIMATION"], package:"gadgetbridge", class:"nodomain.freeyourgadget.gadgetbridge.activities.WakeActivity"})); -} +}; -function spotifyPlaylistDW() { +let spotifyPlaylistDW = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZEVXcRfaeEbxXIgb:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistDM1() { +let spotifyPlaylistDM1 = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZF1E365VyzxE0mxF:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistDM2() { +let spotifyPlaylistDM2 = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZF1E38LZHLFnrM61:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistDM3() { +let spotifyPlaylistDM3 = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZF1E36RU87qzgBFP:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistDM4() { +let spotifyPlaylistDM4 = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZF1E396gGyCXEBFh:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistDM5() { +let spotifyPlaylistDM5 = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZF1E37a0Tt6CKJLP:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistDM6() { +let spotifyPlaylistDM6 = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZF1E36UIQLQK79od:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistDD() { +let spotifyPlaylistDD = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZF1EfWFiI7QfIAKq:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; -function spotifyPlaylistRR() { +let spotifyPlaylistRR = function() { Bluetooth.println(JSON.stringify({t:"intent", action:"android.intent.action.VIEW", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", data:"spotify:user:spotify:playlist:37i9dQZEVXbs0XkE2V8sMO:play", target:"activity" , flags:["FLAG_ACTIVITY_NEW_TASK", "FLAG_ACTIVITY_NO_ANIMATION"/*, "FLAG_ACTIVITY_CLEAR_TOP", "FLAG_ACTIVITY_PREVIOUS_IS_TOP"*/]})); -} +}; // Spotify Remote Menu -var spotifyMenu = { - "" : { title : " ", +let spotifyMenu = { + "" : { title : " Menu ", back: backToGfx }, "Controls" : ()=>{E.showMenu(controlMenu);}, "Search and play" : ()=>{E.showMenu(searchMenu);}, @@ -234,8 +240,8 @@ var spotifyMenu = { }; -var controlMenu = { - "" : { title : " ", +let controlMenu = { + "" : { title : " Controls ", back: () => {if (backToMenu) E.showMenu(spotifyMenu); if (!backToMenu) backToGfx();} }, "Play" : ()=>{Bangle.musicControl("play");}, @@ -246,8 +252,8 @@ var controlMenu = { "Messages Music Controls" : ()=>{load("messagesmusic.app.js");}, }; -var searchMenu = { - "" : { title : " ", +let searchMenu = { + "" : { title : " Search ", back: () => {if (backToMenu) E.showMenu(spotifyMenu); if (!backToMenu) backToGfx();} }, "Search term w/o tags" : ()=>{simpleSearchTerm();}, @@ -258,8 +264,8 @@ var searchMenu = { "Execute search and play with tags" : ()=>{searchPlayWTags();}, }; -var savedMenu = { - "" : { title : " ", +let savedMenu = { + "" : { title : " Saved ", back: () => {if (backToMenu) E.showMenu(spotifyMenu); if (!backToMenu) backToGfx();} }, "Play Discover Weekly" : ()=>{spotifyPlaylistDW();}, @@ -279,3 +285,4 @@ var savedMenu = { Bangle.loadWidgets(); setUI(); gfx(); +} diff --git a/apps/spotrem/metadata.json b/apps/spotrem/metadata.json index a0261ba13..5818d9aee 100644 --- a/apps/spotrem/metadata.json +++ b/apps/spotrem/metadata.json @@ -1,7 +1,7 @@ { "id": "spotrem", "name": "Remote for Spotify", - "version": "0.05", + "version": "0.07", "description": "Control spotify on your android device.", "readme": "README.md", "type": "app", diff --git a/apps/swscroll/ChangeLog b/apps/swscroll/ChangeLog index c650baf72..c5fc9dcb4 100644 --- a/apps/swscroll/ChangeLog +++ b/apps/swscroll/ChangeLog @@ -1 +1,2 @@ 0.01: Inital release. +0.02: Rebasing on latest changes to showScroller_Q3 (https://github.com/espruino/Espruino/commit/2d3c34ef7c2b9fe2118e816aacd2e096adb99596). diff --git a/apps/swscroll/boot.js b/apps/swscroll/boot.js index fc5650cad..2b1b00de3 100644 --- a/apps/swscroll/boot.js +++ b/apps/swscroll/boot.js @@ -1,13 +1,14 @@ -E.showScroller = (function(options) { +E.showScroller = (function(options) { /* options = { h = height c = # of items scroll = initial scroll position scrollMin = minimum scroll amount (can be negative) draw = function(idx, rect) - select = function(idx) + remove = function() + select = function(idx, touch) } - + returns { draw = draw all drawItem(idx) = draw specific item @@ -15,46 +16,13 @@ E.showScroller = (function(options) { */ if (!options) return Bangle.setUI(); // remove existing handlers -var menuShowing = false; -var R = Bangle.appRect; -var Y = Bangle.appRect.y; -var n = Math.ceil(R.h/options.h); -var menuScrollMin = 0|options.scrollMin; -var menuScrollMax = options.h*options.c - R.h; -if (menuScrollMax { - g.reset().clearRect(R.x,R.y,R.x2,R.y2); - g.setClipRect(R.x,R.y,R.x2,R.y2); - var a = YtoIdx(R.y); - var b = Math.min(YtoIdx(R.y2),options.c-1); - for (var i=a;i<=b;i++) - options.draw(i, {x:R.x,y:idxToY(i),w:R.w,h:options.h}); - g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); -}, drawItem : i => { - var y = idxToY(i); - g.reset().setClipRect(R.x,y,R.x2,y+options.h); - options.draw(i, {x:R.x,y:y,w:R.w,h:options.h}); - g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); -}}; -var rScroll = s.scroll&~1; // rendered menu scroll (we only shift by 2 because of dither) -s.draw(); // draw the full scroller -g.flip(); // force an update now to make this snappier Bangle.setUI({ mode : "custom", back : options.back, - swipe : (hor,ver)=>{ + remove : options.remove, + swipe : (_,UD)=>{ pixels = 120; - var dy = ver*pixels; + var dy = UD*pixels; if (s.scroll - dy > menuScrollMax) dy = s.scroll - menuScrollMax-8; // Makes it so the last 'page' has the same position as previous pages. This should be done dynamically (change the static 8 to be a variable) so the offset is correct even when no widget field or title field is present. if (s.scroll - dy < menuScrollMin) @@ -66,7 +34,7 @@ Bangle.setUI({ if (!dy || options.c<=3) return; //options.c<=3 should maybe be dynamic, so 3 would be replaced by a variable dependent on R=Bangle.appRect. It's here so we don't try to scroll if all entries fit in the app rectangle. g.reset().setClipRect(R.x,R.y,R.x2,R.y2); g.scroll(0,dy); - var d = ver*pixels; + var d = UD*pixels; if (d < 0) { g.setClipRect(R.x,R.y2-(1-d),R.x2,R.y2); let i = YtoIdx(R.y2-(1-d)); @@ -92,9 +60,47 @@ Bangle.setUI({ }, touch : (_,e)=>{ if (e.y=0) && i=0) && i { + g.reset().clearRect(R.x,R.y,R.x2,R.y2); + g.setClipRect(R.x,R.y,R.x2,R.y2); + var a = YtoIdx(R.y); + var b = Math.min(YtoIdx(R.y2),options.c-1); + for (var i=a;i<=b;i++) + options.draw(i, {x:R.x,y:idxToY(i),w:R.w,h:options.h}); + g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); +}, drawItem : i => { + var y = idxToY(i); + g.reset().setClipRect(R.x,y,R.x2,y+options.h); + options.draw(i, {x:R.x,y:y,w:R.w,h:options.h}); + g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1); +}}; +var rScroll = s.scroll&~1; // rendered menu scroll (we only shift by 2 because of dither) +s.draw(); // draw the full scroller +g.flip(); // force an update now to make this snappier return s; -}); +}) diff --git a/apps/swscroll/metadata.json b/apps/swscroll/metadata.json index cb345054e..4edbfa2ba 100644 --- a/apps/swscroll/metadata.json +++ b/apps/swscroll/metadata.json @@ -1,7 +1,7 @@ { "id": "swscroll", "name": "Swipe menus", - "version": "0.01", + "version": "0.02", "description": "Replace built in E.showScroller to act on swipe instead of drag. Navigate menus in discrete steps instead of a continuous motion.", "readme": "README.md", "icon": "app.png", diff --git a/apps/widalarm/ChangeLog b/apps/widalarm/ChangeLog new file mode 100644 index 000000000..63568a9bd --- /dev/null +++ b/apps/widalarm/ChangeLog @@ -0,0 +1 @@ +0.01: Moved out of 'alarm' app diff --git a/apps/widalarm/app.png b/apps/widalarm/app.png new file mode 100644 index 000000000..a859dd2ef Binary files /dev/null and b/apps/widalarm/app.png differ diff --git a/apps/widalarm/metadata.json b/apps/widalarm/metadata.json new file mode 100644 index 000000000..b91457138 --- /dev/null +++ b/apps/widalarm/metadata.json @@ -0,0 +1,15 @@ +{ + "id": "widalarm", + "name": "Alarms Widget", + "version": "0.01", + "description": "Displays an alarm icon in the widgets bar if any alarm is active", + "icon": "app.png", + "type": "widget", + "tags": "tool,alarm,widget", + "supports": [ "BANGLEJS", "BANGLEJS2" ], + "provides_widgets" : ["alarm"], + "default" : true, + "storage": [ + { "name": "widalarm.wid.js", "url": "widget.js" } + ] +} diff --git a/apps/alarm/widget.js b/apps/widalarm/widget.js similarity index 100% rename from apps/alarm/widget.js rename to apps/widalarm/widget.js diff --git a/apps/widalarmeta/metadata.json b/apps/widalarmeta/metadata.json index b6d8bd62b..ef9f55ba8 100644 --- a/apps/widalarmeta/metadata.json +++ b/apps/widalarmeta/metadata.json @@ -8,6 +8,7 @@ "type": "widget", "tags": "widget", "supports": ["BANGLEJS","BANGLEJS2"], + "provides_widgets" : ["alarm"], "screenshots" : [ { "url":"screenshot.png" } ], "storage": [ {"name":"widalarmeta.wid.js","url":"widget.js"} diff --git a/apps/widbat/metadata.json b/apps/widbat/metadata.json index 0f040396f..993310eb2 100644 --- a/apps/widbat/metadata.json +++ b/apps/widbat/metadata.json @@ -6,6 +6,8 @@ "icon": "widget.png", "type": "widget", "tags": "widget,battery", + "provides_widgets" : ["battery"], + "default" : true, "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"widbat.wid.js","url":"widget.js"} diff --git a/apps/widbata/metadata.json b/apps/widbata/metadata.json index 26968a7d7..ddc901e80 100644 --- a/apps/widbata/metadata.json +++ b/apps/widbata/metadata.json @@ -10,6 +10,7 @@ "readme": "README.md", "description": "Shows the current battery level status in the top right using the clocks colour theme", "tags": "widget,battery", + "provides_widgets" : ["battery"], "storage": [ {"name":"widbata.wid.js","url":"widbata.wid.js"} ] diff --git a/apps/widbatpc/metadata.json b/apps/widbatpc/metadata.json index 7da4e3e0c..953f8d345 100644 --- a/apps/widbatpc/metadata.json +++ b/apps/widbatpc/metadata.json @@ -7,6 +7,7 @@ "icon": "widget.png", "type": "widget", "tags": "widget,battery", + "provides_widgets" : ["battery"], "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "screenshots": [{"url":"widbatpc.full.jpg"},{"url":"widbatpc.part.jpg"}], diff --git a/apps/widbatv/metadata.json b/apps/widbatv/metadata.json index 37cf6197b..d4ef28315 100644 --- a/apps/widbatv/metadata.json +++ b/apps/widbatv/metadata.json @@ -6,6 +6,7 @@ "icon": "widget.png", "type": "widget", "tags": "widget,battery", + "provides_widgets" : ["battery"], "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"widbatv.wid.js","url":"widget.js"} diff --git a/apps/widbt/metadata.json b/apps/widbt/metadata.json index e2d5082a5..1623db7a1 100644 --- a/apps/widbt/metadata.json +++ b/apps/widbt/metadata.json @@ -6,6 +6,8 @@ "icon": "widget.png", "type": "widget", "tags": "widget,bluetooth", + "provides_widgets" : ["bluetooth"], + "default" : true, "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"widbt.wid.js","url":"widget.js"} diff --git a/apps/widbt_notify/metadata.json b/apps/widbt_notify/metadata.json index 36905a340..5e3f15af2 100644 --- a/apps/widbt_notify/metadata.json +++ b/apps/widbt_notify/metadata.json @@ -6,6 +6,7 @@ "icon": "widget.png", "type": "widget", "tags": "widget,bluetooth", + "provides_widgets" : ["bluetooth"], "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"widbt_notify.wid.js","url":"widget.js"}, @@ -13,5 +14,5 @@ ], "data": [ {"name":"widbt_notify.json"} - ] + ] } diff --git a/apps/widbthide/metadata.json b/apps/widbthide/metadata.json index 59b13adb4..e3ac5cd54 100644 --- a/apps/widbthide/metadata.json +++ b/apps/widbthide/metadata.json @@ -6,6 +6,7 @@ "icon": "widget.png", "type": "widget", "tags": "widget,bluetooth", + "provides_widgets" : ["bluetooth"], "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ {"name":"widbthide.wid.js","url":"widget.js"} diff --git a/apps/widmessages/metadata.json b/apps/widmessages/metadata.json index 0c3ac7e05..080e19273 100644 --- a/apps/widmessages/metadata.json +++ b/apps/widmessages/metadata.json @@ -10,6 +10,8 @@ "screenshots": [{"url": "screenshot.gif"}], "dependencies" : { "messageicons":"module" }, "provides_modules" : ["messagewidget"], + "provides_widgets" : ["message"], + "default" : true, "readme": "README.md", "storage": [ {"name":"messagewidget","url":"lib.js"}, diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index 0a4765d9c..5af6f1aa1 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -76,7 +76,7 @@ const APP_KEYS = [ 'id', 'name', 'shortName', 'version', 'icon', 'screenshots', 'description', 'tags', 'type', 'sortorder', 'readme', 'custom', 'customConnect', 'interface', 'storage', 'data', 'supports', 'allow_emulator', - 'dependencies', 'provides_modules' + 'dependencies', 'provides_modules', 'provides_widgets', "default" ]; const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'supports', 'noOverwrite']; const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate']; @@ -168,8 +168,8 @@ apps.forEach((app,appIdx) => { if (app.dependencies) { if (("object"==typeof app.dependencies) && !Array.isArray(app.dependencies)) { Object.keys(app.dependencies).forEach(dependency => { - if (!["type","app","module"].includes(app.dependencies[dependency])) - ERROR(`App ${app.id} 'dependencies' must all be tagged 'type/app/module' right now`, {file:metadataFile}); + if (!["type","app","module","widget"].includes(app.dependencies[dependency])) + ERROR(`App ${app.id} 'dependencies' must all be tagged 'type/app/module/widget' right now`, {file:metadataFile}); if (app.dependencies[dependency]=="type" && !METADATA_TYPES.includes(dependency)) ERROR(`App ${app.id} 'type' dependency must be one of `+METADATA_TYPES, {file:metadataFile}); }); diff --git a/core b/core index 3a953179b..2a89ea64f 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 3a953179b7bb9f574d4e77d5f34b6b7deee1e884 +Subproject commit 2a89ea64f7874b9264572f68836fe8ecd0a6b191 diff --git a/defaultapps_banglejs2.json b/defaultapps_banglejs2.json index 04bd44504..f96f81f60 100644 --- a/defaultapps_banglejs2.json +++ b/defaultapps_banglejs2.json @@ -1 +1 @@ -["boot","launch","antonclk","health","setting","about","widbat","widbt","widlock","widid"] +["boot","launch","antonclk","health","setting","about","alarm","widbat","widbt","widlock","widid"] diff --git a/lang/de_DE.json b/lang/de_DE.json index ef22b588f..84f29a6c2 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -20,7 +20,7 @@ "On": "Ein", "Off": "Aus", "Ok": "OK", - "New Timer": "Neuer Kurzzeitwecker", + "New Timer": "Neuer Timer", "(repeat)": "(Wiederholung)", "music": "Musik", "Keep Msgs": "Nachrichten behalten", @@ -148,7 +148,7 @@ "Whitelist": "Whitelist", "Select Clock": "Uhr auswählen", "Disable": "Deaktivieren", - "Timer": "Kurzzeitwecker", + "Timer": "Timer", "Error in settings": "Fehler in den Einstellungen", "Set Time": "Zeit einstellen", "ALARM": "ALARM", diff --git a/lang/sv_SE.json b/lang/sv_SE.json index 6e0f30fa4..2c2ff5acf 100644 --- a/lang/sv_SE.json +++ b/lang/sv_SE.json @@ -6,34 +6,34 @@ "Hours": "Timmar", "Minutes": "Minuter", "Enabled": "Aktiverad", - "New Alarm": "Ny alarm", + "New Alarm": "Nytt larm", "Save": "Spara", "Back": "Tillbaka", "Repeat": "Upprepning", "Delete": "Radera", - "ALARM!": "ALURH!", + "ALARM!": "LARM!", "Sleep": "Sömn", "circle 3": "cirkel 3", "circle 1": "cirkel 1", "music": "musik", "week": "vecka", "Keep Msgs": "Behåll meddelanden", - "Auto snooze": "Automatisk snooze", + "Auto snooze": "Auto-snooza", "step length": "steglängd", "Circle": "Cirkel", "data": "uppgifter", - "colorize icon": "färglägga ikonen", - "min. confidence": "Min. förtroende", - "show widgets": "visa widgets", + "colorize icon": "färglägg ikon", + "min. confidence": "min. konfidens", + "show widgets": "visa widgetar", "valid period": "giltig period", "Heartrate": "Hjärtfrekvens", - "distance goal": "mål för distans", + "distance goal": "distansmål", "circle 4": "cirkel 4", "circle count": "antal cirklar", "minimum": "minimum", "maximum": "maximal", "New Timer": "Ny timer", - "battery warn": "batteri varning", + "battery warn": "batterivarning", "heartrate": "hjärtfrekvens", "circle 2": "cirkel 2", "(repeat)": "(upprepning)", @@ -42,30 +42,30 @@ "No Messages": "Inga meddelanden", "Show clocks": "Visa klockor", "STEPS": "STEG", - "TAP right top/bottom": "TAP höger upp/ner", + "TAP right top/bottom": "KNACKA höger upp/ner", "View Message": "Visa meddelande", "Mark Unread": "Markera oläst", - "Are you sure": "Är du säker på att", + "Are you sure": "Är du säker", "Delete all messages": "Radera alla meddelanden", - "Record Run": "Rekordkörning", + "Record Run": "Spåra löprunda", "Unread timer": "Oläst timer", "Vibration": "Vibrationer", - "Utils": "Användaruppgifter", + "Utils": "Verktyg", "Quiet Mode": "Tyst läge", "Passkey BETA": "Passkey BETA", "Dark BW": "Mörk BW", - "BTNs 1:startlap 2:exit 3:reset": "BTN 1:startlap 2:exit 3:reset", - "start&lap/reset, BTN1: EXIT": "start&lap/återställning, BTN1: EXIT", + "BTNs 1:startlap 2:exit 3:reset": "BTN 1:starta varv 2:lämna 3:återställ", + "start&lap/reset, BTN1: EXIT": "starta&varv/återställ, BTN1: LÄMNA", "BLE": "BLE", "Programmable": "Programmerbar", - "Launcher Settings": "Inställningar för lanseringen", - "Vector font size": "Vektor teckensnittsstorlek", + "Launcher Settings": "Inställningar för launchern", + "Vector font size": "Storlek vektortypsnitt", "Font": "Typsnitt", "Yes\ndefinitely": "Ja\ndefinitivt", "App Source\nNot found": "App-källa\nEj funnen", - "Make Connectable": "Gör det möjligt att ansluta", + "Make Connectable": "Gör anslutningsbar", "HID": "HID", - "Bluetooth": "Bluetooth", + "Bluetooth": "Blåtand", "Apps": "Appar", "Piezo": "Piezo", "LCD": "LCD", @@ -73,46 +73,46 @@ "Light BW": "Ljus BW", "Background": "Bakgrund", "Remove": "Ta bort", - "Highlight BG": "Markera BG", + "Highlight BG": "Markering BG", "Customize": "Anpassa", - "Highlight FG": "Highlight FG", + "Highlight FG": "Markering FG", "Background 2": "Bakgrund 2", "LCD Brightness": "Ljusstyrka på LCD-skärmen", "Add Device": "Lägg till enhet", - "Wake on BTN1": "Vakna på BTN1", - "Wake on BTN2": "Vakna på BTN2", - "Twist Timeout": "Twist Timeout", + "Wake on BTN1": "Vakna av BTN1", + "Wake on BTN2": "Vakna av BTN2", + "Twist Timeout": "Vridning Timeout", "Wake on Touch": "Vakna vid beröring", "LCD Timeout": "LCD Timeout", "Foreground": "Förgrund", - "Connect device\nto add to\nwhitelist": "Anslut enhet\nför att lägga till\nvitlista", - "Wake on FaceUp": "Vakna på FaceUp", + "Connect device\nto add to\nwhitelist": "Anslut enhet\nför att lägga till\ni vitlistan", + "Wake on FaceUp": "Skärm upp väcker", "Twist Threshold": "Tröskelvärde för vridning", - "Wake on BTN3": "Wake på BTN3", + "Wake on BTN3": "Vakna av BTN3", "Clock Style": "Klockstil", "Time Zone": "Tidszon", "Twist Max Y": "Vridning Max Y", - "Stay Connectable": "Håll dig tillgänglig", - "This will remove everything": "Detta kommer att ta bort allt", + "Stay Connectable": "Håll anslutningsbar", + "This will remove everything": "Detta kommer ta bort allt", "Turn Off": "Stäng av", "Connectable": "Anslutningsbar", - "Flattening battery - this can take hours.\nLong-press button to cancel": "Platta batterier - detta kan ta flera timmar.\nTryck länge på knappen för att avbryta", - "Reset to Defaults": "Återställ till standardvärden", + "Flattening battery - this can take hours.\nLong-press button to cancel": "Töm batteri - detta kan ta flera timmar.\nTryck länge på knappen för att avbryta", + "Reset to Defaults": "Återställ standardvärden", "Utilities": "Verktyg", - "Flatten Battery": "Platta batterier", - "Debug Info": "Info om felsökning", - "Reset Settings": "Återställa inställningar", - "Wake on Twist": "Väckning på Twist", - "Compact Storage": "Kompakt förvaring", + "Flatten Battery": "Töm batteri", + "Debug Info": "Felsökningsinfo", + "Reset Settings": "Återställ inställningar", + "Wake on Twist": "Vakna av vridning", + "Compact Storage": "Komprimera lagring", "Log": "Logg", "Rewrite Settings": "Omskrivning av inställningar", - "Compacting...\nTakes approx\n1 minute": "Komprimering...\nTar ca.\n1 minut", + "Compacting...\nTakes approx\n1 minute": "Komprimerar...\nTar ca.\n1 minut", "Storage": "Lagring", "Second": "Andra", "App Settings": "App-inställningar", "Invalid settings": "Ogiltiga inställningar", - "Minute": "Protokoll", - "Sleep Phase Alarm": "Larm om sömnfas", + "Minute": "Minut", + "Sleep Phase Alarm": "Sömnfaslarm", "No app has settings": "Ingen app har inställningar", "Hour": "Timme", "No Clocks Found": "Inga klockor hittades", @@ -124,16 +124,16 @@ "TIMER": "TIMER", "on": "på", "OFF": "OFF", - "Side": "Sidan", + "Side": "Sida", "Sort Order": "Sortering", "Left": "Vänster", "Right": "Höger", "Reset All": "Återställ alla", - "Widgets": "Widgets", + "Widgets": "Widgetar", "goal": "mål", "Vibrate": "Vibrera", "Message": "Meddelande", - "Beep": "Piper", + "Beep": "Pip", "Disable": "Inaktivera", "Select Clock": "Välj klocka", "Locale": "Lokalisering", @@ -145,14 +145,14 @@ "Timer": "Timer", "BACK": "TILLBAKA", "Error in settings": "Fel i inställningarna", - "Whitelist": "Whitelist", - "ALARM": "ALARM", + "Whitelist": "Vitlista", + "ALARM": "LARM", "Hide": "Dölj", "Connected": "Ansluten", "Show": "Visa", "On": "På", "Ok": "Ok", - "No": "Ingen", + "No": "Nej", "Settings": "Inställningar", "steps": "steg", "back": "tillbaka", @@ -162,7 +162,7 @@ "Loading": "Laddar", "Music": "Musik", "color": "färg", - "off": "off", + "off": "av", "Off": "Av", "Theme": "Tema", "one": "ett", @@ -197,4 +197,4 @@ "ten to *$2": "tio i *$2", "five to *$2": "fem i *$2" } -} \ No newline at end of file +} diff --git a/modules/README.md b/modules/README.md index 3f8e90b06..fcb403bd5 100644 --- a/modules/README.md +++ b/modules/README.md @@ -18,28 +18,6 @@ so you may see the error "Module not found" in the IDE when sendin To fix this you have three options: -### Host your own App Loader and upload from that - -This is reasonably easy to set up, but it's more difficult to make changes and upload: - -* Follow the steps here to set up your own App Loader: https://www.espruino.com/Bangle.js+App+Loader -* Make changes to that repository -* Refresh and upload your app from the app loader (you can have the IDE connected - at the same time so you can see any error messages) - -### Upload the module to the Bangle's internal storage - -This allows you to develop both the app and module very quickly, but the app is -uploaded in a slightly different way to what you'd get when you use the App Loader -or the method below: - -* Load the module's source file in the Web IDE -* Click the down-arrow below the upload button, then `Storage` -* Click `New File`, type `your_module_name` as the name (with no `.js` extension), click `Ok` -* Now Click the `Upload` icon. - -You can now upload the app direct from the IDE. You can even leave a second Web IDE window open -(one for the app, one for the module) to allow you to change the module. ### Change the Web IDE search path to include Bangle.js modules @@ -56,3 +34,30 @@ The next time you upload your app, the module will automatically be included. **Note:** You can optionally use `https://raw.githubusercontent.com/espruino/BangleApps/master/modules|https://www.espruino.com/modules` as the module URL to pull in modules direct from the development app loader (which could be slightly newer than the ones on https://banglejs.com/apps) + + +### Host your own App Loader and upload from that + +This is reasonably easy to set up, but it's more difficult to make changes and upload: + +* Follow the steps here to set up your own App Loader: https://www.espruino.com/Bangle.js+App+Loader +* Make changes to that repository +* Refresh and upload your app from the app loader (you can have the IDE connected + at the same time so you can see any error messages) + + +### Upload the module to the Bangle's internal storage + +This allows you to develop both the app and module very quickly, but the app is +uploaded in a slightly different way to what you'd get when you use the App Loader +or the method below: + +* Load the module's source file in the Web IDE +* Click the down-arrow below the upload button, then `Storage` +* Click `New File`, type `your_module_name` as the name (with no `.js` extension), click `Ok` +* Now Click the `Upload` icon. + +You can now upload the app direct from the IDE. You can even leave a second Web IDE window open +(one for the app, one for the module) to allow you to change the module. + +