Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
74b78df
Create app.js
RKBoss6 Oct 15, 2025
b0cd7e6
Update app.js
RKBoss6 Oct 16, 2025
633b004
Create metadata.json
RKBoss6 Oct 16, 2025
540bac1
Add files via upload
RKBoss6 Oct 16, 2025
d235d46
Add files via upload
RKBoss6 Oct 16, 2025
3468539
Add settings management for Daily Color Clock
RKBoss6 Oct 16, 2025
91d0dde
Add additional screenshots to metadata.json
RKBoss6 Oct 16, 2025
1510030
Add default color settings to default.json
RKBoss6 Oct 16, 2025
e6f285a
Create README.md for Daily Color Clock
RKBoss6 Oct 16, 2025
21c7e0e
Update README.md
RKBoss6 Oct 16, 2025
59bd5bb
Add files via upload
RKBoss6 Oct 16, 2025
76c23a0
Delete apps/dailycolorclk/icon.png
RKBoss6 Oct 16, 2025
8c5a1e5
Add files via upload
RKBoss6 Oct 16, 2025
31704d5
Fix icon filename case in metadata.json
RKBoss6 Oct 16, 2025
0adad96
Add app-icon.js to handle icon decompression
RKBoss6 Oct 16, 2025
764c464
Remove unused graphics buffer initialization
RKBoss6 Oct 16, 2025
25dd1bb
Clean up unused variables in app.js
RKBoss6 Oct 16, 2025
f1327d0
Add variables x and y to app.js
RKBoss6 Oct 16, 2025
2bbd1ad
Cleanup: Remove unused variables in app.js
RKBoss6 Oct 16, 2025
8e2c78b
Update app.js
RKBoss6 Oct 16, 2025
e95d73a
Merge branch 'espruino:master' into dailycolorclk
RKBoss6 Oct 16, 2025
776d2b7
Fix minute drawing and text alignment
RKBoss6 Oct 17, 2025
646412f
Refactor color change logic and adjust drawing area
RKBoss6 Oct 18, 2025
83f2e2c
Update app.js
RKBoss6 Oct 19, 2025
d3703a2
Correct typo in oldColorIdx variable assignment
RKBoss6 Oct 19, 2025
119e141
Fix typo in indexOf method for background colors
RKBoss6 Oct 19, 2025
af204b2
Refactor clockInfoMenu highlight color logic
RKBoss6 Oct 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added apps/dailycolorclk/Icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions apps/dailycolorclk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Daily Color Clock
A clock that randomly changes the accent color every day to freshen up the clock face every day.

This is forked from `Slope Clock ++`

![](Scr4.png)
## Settings
Choose what colors are enabled or disabled, which affects the colors it can be.

#### <b>Dithered colors</b>:
Colors that are dithered, which may affect quality.



## Creator
RKBoss6
Binary file added apps/dailycolorclk/Scr1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/dailycolorclk/Scr2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/dailycolorclk/Scr3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/dailycolorclk/Scr4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/dailycolorclk/app-icon.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

180 changes: 180 additions & 0 deletions apps/dailycolorclk/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
{ // must be inside our own scope here so that when we are unloaded everything disappears

let settings;
let getSettings=function(){
settings = Object.assign(
require("Storage").readJSON("dailycolorclk.default.json", true) || {},
require("Storage").readJSON("dailycolorclk.json", true) || {}
);
}
let writeSettings=function(){
require("Storage").writeJSON("dailycolorclk.json", settings);
}
getSettings();

const fontBitmap = E.toString(require('heatshrink').decompress(atob('AC1+A40H/gIGn/4A4sB//wDI3/8AIFj//wAIFv/+EQ4rGESROHDI4rBCA0BGYwAKDYI+Ogf/MI1/MI0P/4iFFIIABEQk/A4IiEPIIZGFIP/OQgpC//AFIw7EFIR6EFJAHCFJBLDFMKWBFJPwHQ6XEGQS6FFIy5CYQwiBFIgiCZQwiBcgwAkNQRQFa4SUIBAgQDBAZpCAAJbDToYsEA4bJDFQh+DaAagEA4iYCDIo9CGYg0DJoIVBVQZNBF4QeBFYIMBX4QEDn5SDj5gCZAl/K4IiB4CXDEQaPEERZ1CAgYdBCIRbBE4JoRRaDhCDIquIK4IZFaJIIEOoQ9EdYYRECAYsDOgYAaMAIoEFQYRGV4gZEaQbEGDIpcEYgYZIHgzeDDIrRGga3HbQovCv4IEF4IZFEQTIFEQQZFEQLrFEQTrFEQQ8FESYASg4VHZAcDBgUfZAc/Vw0BBgSuEj4MCn4iDBgROBCoT4DAYKhDBgQZBPwZoEBg4VBWQSLDCoIDBRYnADoQMBCoIDBYYQiBIAauEn4dBXQQiCDISxCEQfAZYYiEJgIiE/z/DEQYADv7RG/L0Hw70G/i7DGIfAEQQrD/wnBVwYAB8AnBboRLDEQZ/CNQQiCBAQeCbwYQCEQYICAYQiCCwIDCADEBwAIGg/gBoYvCj5NCAgl/CIZ1EKwRSDAYIsCcYRaECoIiDQQgiD/CuDEQY0BBgIiEaIYiDaInB/+Begn+g/+AgIrBX4PAj/4E4IrBh4OBMwINBK4M/BwWABoQdBcAYNBEQWANQQiD/5dCPQZfBdgV/EQRSBAAZbBC4IAENAYAERYYADRYgADYAQrFZAf//YCBQQRXB//HDIgIB/wuCfIZKBUAIzCBAJbBG4LiCAAaeBA4oAJFQYADh5ECCArdCAAY/BQIIAEdQYQFEQxNBEQpzCEQqWCA4i5CEQp4BEQzHELoatFCAgiEJgP+v4iELoPhEQgQCAQJdGj4iDLoQcBEQYQCLAIiCLoQlCBIQECfopmCJ4pEBAAYsBEQQADEXyfFdYodBegyLFcgj0FEQP+DIwAbhgIHHoRoCGQMf8BoE/hGDRYbsBNISLD4AcCRYgVB/AiE/0D/4rBEQf4DwKuF8EPVw2An6uFGIKVCEQgEBFYJFEAgOAWYQ6BAgJOCDoMPFAN/JwJsCn/wEQsAEROAv4iF/+HegQiDH4YiEAAT5DEQJZCEQZ8EEQZ8DVwcAFYSCCEQKFDaIZABDIgiCRwQzCAAQ9CM4IIFCAodCA4oASn4HGRgKBBAAhWEAARxCCIjlDBAj/ECAy/CCAqLCCAhpECAY9EA4Y0DKgLRFCAfgFYYQCHQL0CCAfwG4IrBcAfAAgJXBHYQZBh5XCa4RLBn4CBKoYfBEQn8EQ/jAoM/EQf+I4IeBIoJACn5oEg5UCNAkf8D8CRYd+LIg8BgICBSoYQBgzqCVwpiEcYqcFYIi/DAAI9CcQYIDCAoaCA4oAOj5JFJYTMCE4rvCAAKLCGAkPEQ0BAgQiEn6uDEQQeBEQyuEDoTKBEQqDCEQqmCEQjADEQgHCEQgpBEQvBdYYiDfgb5BcAgQDa4bIEJQTZFIQYyCEQopCEQqoDEQbhEMooiF8DRFFIoiDaQgiCFIgiDeg4pFbogiFFIoAfh5ZFFgKMG+BaBIIYFB+B0BBAbQB+aWEgYFB96OEeQbaJ/+ADIbKFDIo0CDIrkBegorCaIf8VQc//wKB8EfFYQFBFoINBK4I8BwEfAoJXCQ4TCBBoQUCGwOASoYUBg4FBEQnAn/8CYIiC/+BRIIEBEQJJBAAP9NCiLOW4QrDW4jIBAAbiD//7DIhgB/+PZAg9B/guBfogNBFwJNBAAitDBAoQGAB9/HIQADHQJcCHggIGPQQaFToSrBAASUDKYxmDmAZEXoMDVwpeBn6uFfoLRGwE/aIv+fIUAg4DBv/4XYK/CHQP/8L0DGIIcBz42CDoOAH4YiBh4ZBH4YiCaoLlCEQxZDIAQ/BQoYFBKgL0EQQODCAhoECAYoDWAhLDHYZLEYIiuCCAhUDaQoQHGgYQEBAQQEHob0FBAJUCAAjqCAD8DBA9/SIM/SgQ9CKQQIDj7TCIAhOCv5iDDILTCLQaeBaYXgSoihCFYaCCv4rDERrBEIoQlBFYfwAQKXENAV/VAl4AQN+RJQ=')));

Graphics.prototype.setFontPaytoneOne = function(scale) {
this.setFontCustom(fontBitmap, 46, atob("ER0mGCMjJiMkIiUkEg=="), 70|65536);
return this;
}

let drawTimeout;


const slopeHeight = 90;
const fontBorder = 13;
const hoursYPos=68;
const minOffset=4; //offset from slope
const slopeBorder = 4;

let R;
let dateStr = "";
let bgColor = settings.colorSaved;
let changeBGColor = function() {
let bgColors = [];
if (settings.colorYellow) bgColors.push("#ff0");
if (settings.colorCyan) bgColors.push("#0ff");
if (settings.colorMagenta) bgColors.push("#f0f");
if (settings.colorWhite) bgColors.push("#fff");
if (settings.colorRed) bgColors.push("#f00");
if (settings.colorGreen) bgColors.push("#0f0");
if (settings.colorBlue) bgColors.push("#00f");
if (settings.colorOrange) bgColors.push("#FC6A03");
if (settings.colorPurple) bgColors.push("#B200ED");
if (settings.colorBlack) bgColors.push("#000");

let oldColorIdx = bgColors.indexOf(settings.colorSaved);
if (oldColorIdx !== -1) bgColors.splice(oldColorIdx, 1);
let col = bgColors[(Math.random()*bgColors.length)|0] || "#000";

settings.colorSaved = col;
writeSettings();
}
let checkForColorChange = function() {
let dayNow = new Date().getDay();
if (settings.dayChanged != dayNow) {
settings.dayChanged = dayNow;
changeBGColor();
load();
}
}

//draws bg color once, erases background
let preDraw=function(){
g.setColor(g.theme.bg).fillRect(0,0,g.getWidth(),g.getHeight());
g.setColor(bgColor).fillRect(
0,slopeHeight,g.getWidth(), g.getHeight()
);

}
// Draw the hour, minute, and date
let draw = function() {

checkForColorChange();

if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(draw, 60000 - (Date.now() % 60000));

R = Bangle.appRect;


var date = new Date();
var local_time = require("locale").time(date, 1);
var hourStr = " "+local_time.split(":")[0].padStart(2,'0')+" ";
var minStr = " "+local_time.split(":")[1].padStart(2,'0')+" ";

dateStr = require("locale").dow(date,1) + ', ' +
require("locale").month(date,1) + " " + date.getDate();

//clear old hour
g.setColor(g.theme.bg);
g.fillRect(0,24,96,88);
// Draw hour
g.setColor(g.theme.fg)
.setFontAlign(-1, 0)
.setFont("PaytoneOne")
.drawString(hourStr, fontBorder, hoursYPos);






// draw minutes
var yo = slopeHeight + minOffset;
g.setColor(bgColor);
//clear old minutes
g.fillRect(92,92,g.getWidth(),152);
g.setFontAlign(1, -1).setFont("PaytoneOne")
.setColor(g.theme.bg).drawString(minStr,g.getWidth()-7, yo);

// Transition bar
g.setColor(g.theme.bg).fillRect(
0,slopeHeight-slopeBorder,g.getWidth(), slopeHeight
);
// Draw date
g.setColor(g.theme.bg)
.setFontAlign(0, 0)
.setFont("Vector",16)
.drawString(dateStr, R.x + R.w/2, R.y+R.h-13);

};



// Clock info menus
let clockInfoDraw = (itm, info, options) => {
let texty = options.y+41;
g.reset().setClipRect(options.x, options.y, options.x+options.w-1, options.y+options.h-1);
g.setFont("Vector",15).setBgColor(options.bg).clearRect(options.x, texty-15, options.x+options.w-2, texty);

g.setColor(options.focus ? options.hl : options.fg);
if (options.x < g.getWidth()/2) {
let x = options.x+2;
if (info.img) g.clearRect(x, options.y, x+23, options.y+23).drawImage(info.img, x, options.y);
g.setFontAlign(-1,1).drawString(info.text, x,texty);
} else {
let x = options.x+options.w-3;
if (info.img) g.clearRect(x-23, options.y, x, options.y+23).drawImage(info.img, x-23, options.y);
g.setFontAlign(1,1).drawString(info.text, x,texty);
}
g.setClipRect(0,0,g.getWidth()-1, g.getHeight()-1);
};

let clockInfoItems = require("clock_info").load();
let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, {
app:"slopeclockpp",x:98, y:38, w:70, h:50,
draw : clockInfoDraw, bg : g.theme.bg, fg : g.theme.fg, hl :
(g.theme.fg===g.toColor(bgColor))?"#f00":bgColor
});
let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, {
app:"slopeclockpp",x:10, y:102, w:70, h:50,
draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg, hl :
(g.theme.fg===g.toColor(bgColor))?"#f00":g.theme.fg
});

// Show launcher when middle button pressed
Bangle.setUI({
mode : "clock",
remove : function() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
delete Graphics.prototype.setFontPaytoneOne;
clockInfoMenu.remove();
delete clockInfoMenu;
clockInfoMenu2.remove();
delete clockInfoMenu2;
},
redraw: draw,
});

Bangle.loadWidgets();
if (settings.hideWidgets) require("widget_utils").swipeOn();
else setTimeout(Bangle.drawWidgets,0);
preDraw();
draw();
clockInfoMenu.redraw();
clockInfoMenu2.redraw();

}
12 changes: 12 additions & 0 deletions apps/dailycolorclk/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"colorRed": true,
"colorGreen": true,
"colorBlue": true,
"colorYellow": true,
"colorMagenta": true,
"colorCyan": true,
"colorBlack": true,
"colorWhite": true,
"colorOrange": true,
"colorPurple": true
}
29 changes: 29 additions & 0 deletions apps/dailycolorclk/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"id": "dailycolorclk",
"name": "Daily Color Clock",
"shortName":"Daily Color",
"icon": "Icon.png",
"version":"0.01",
"description": "A clock with 2 ClockInfos and a bar of color at the bottom that changes color every day. Forked from Slope Clock ++",
"type":"clock",
"tags": "clock,clkinfo",
"author":"RKBoss6",
"supports": ["BANGLEJS2"],
"screenshots" : [ { "url":"Scr1.png" },
{ "url":"Scr2.png" },{ "url":"Scr3.png" },{ "url":"Scr4.png" }],
"dependencies" : { "clock_info":"module"},
"allow_emulator":true,
"readme":"README.md",
"storage": [
{"name":"dailycolorclk.app.js","url":"app.js"},
{"name":"dailycolorclk.img","url":"app-icon.js","evaluate":true},
{"name":"dailycolorclk.settings.js","url":"settings.js"},
{"name":"dailycolorclk.default.json","url":"default.json"}
],
"data": [
{"name":"dailycolorclk.settings.json"},
{"name":"dailycolorclk.json"}
]
}


76 changes: 76 additions & 0 deletions apps/dailycolorclk/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
(function(back) {
const SETTINGS_FILE = "dailycolorclk.json";
const storage = require('Storage');
let settings = Object.assign(
storage.readJSON("dailycolorclk.default.json", true) || {},
storage.readJSON(SETTINGS_FILE, true) || {}
);

function save(key, value) {
settings[key] = value;
storage.write(SETTINGS_FILE, settings);
}
function showDitheringMenu(){
var menu={
"< Back": () => showMainMenu,
/*LANG*/'Orange (Dithered)': {
value: !!settings.colorOrange,
onchange: x => save('colorOrange', x),
},
/*LANG*/'Purple (Dithered)': {
value: !!settings.colorPurple,
onchange: x => save('colorPurple', x),
}
}
E.showMenu(menu);
}
function showMainMenu() {
let menu ={
'': { 'title': 'Daily Color Clock' },
/*LANG*/'< Back': back,
/*LANG*/'Hide Widgets': {
value: !!settings.hideWidgets,
onchange: x => save('hideWidgets', x),
},
/*LANG*/'Dithered Colors': () => {showDitheringMenu()},
/*LANG*/'Red': {
value: !!settings.colorRed,
onchange: x => save('colorRed', x),
},
/*LANG*/'Green': {
value: !!settings.colorGreen,
onchange: x => save('colorGreen', x),
},
/*LANG*/'Blue': {
value: !!settings.colorBlue,
onchange: x => save('colorBlue', x),
},
/*LANG*/'Magenta': {
value: !!settings.colorMagenta,
onchange: x => save('colorMagenta', x),
},
/*LANG*/'Cyan': {
value: !!settings.colorCyan,
onchange: x => save('colorCyan', x),
},
/*LANG*/'Yellow': {
value: !!settings.colorYellow,
onchange: x => save('colorYellow', x),
},
/*LANG*/'Black': {
value: !!settings.colorBlack,
onchange: x => save('colorBlack', x),
},
/*LANG*/'White': {
value: !!settings.colorWhite,
onchange: x => save('colorWhite', x),
},


};
E.showMenu(menu);
}


showMainMenu();
})