mirror of https://github.com/espruino/BangleApps
124 lines
5.4 KiB
JavaScript
124 lines
5.4 KiB
JavaScript
const storage = require("Storage");
|
|
|
|
const SETTINGS_FILE = "infoclk.json";
|
|
|
|
let defaultConfig = {
|
|
dualStageUnlock: 0,
|
|
|
|
seconds: {
|
|
// Displaying the seconds can reduce battery life because the CPU must wake up more often to update the display.
|
|
// The seconds will be shown unless one of these conditions is enabled here, and currently true.
|
|
hideLocked: false, // Hide the seconds when the display is locked.
|
|
hideBattery: 20, // Hide the seconds when the battery is at or below a defined percentage.
|
|
hideTime: true, // Hide the seconds when between a certain period of time. Useful for when you are sleeping and don't need the seconds
|
|
hideStart: 2200, // The time when the seconds are hidden: first 2 digits are hours on a 24 hour clock, last 2 are minutes
|
|
hideEnd: 700, // The time when the seconds are shown again
|
|
hideAlways: false, // Always hide (never show) the seconds
|
|
forceWhenUnlocked: 1, // Force the seconds to be displayed when the watch is unlocked, no matter the other settings. 0 = never, 1 = first or second stage unlock, 2 = second stage unlock only
|
|
},
|
|
|
|
date: {
|
|
// Settings related to the display of the date
|
|
mmdd: true, // If true, display the month first. If false, display the date first.
|
|
separator: '-', // The character that goes between the month and date
|
|
monthName: false, // If false, display the month as a number. If true, display the name.
|
|
monthFullName: false, // If displaying the name: If false, display an abbreviation. If true, display a full name.
|
|
dayFullName: false, // If false, display the day of the week's abbreviation. If true, display the full name.
|
|
},
|
|
|
|
bottomLocked: {
|
|
display: 'weather' // What to display in the bottom row when locked:
|
|
// 'weather': The current temperature and weather description
|
|
// 'steps': Step count
|
|
// 'health': Step count and bpm
|
|
// 'progress': Day progress bar
|
|
// false: Nothing
|
|
},
|
|
|
|
shortcuts: [
|
|
//8 shortcuts, displayed in the bottom half of the screen (2 rows of 4 shortcuts) when unlocked
|
|
// false = no shortcut
|
|
// '#LAUNCHER' = open the launcher
|
|
// any other string = name of app to open
|
|
'stlap', 'keytimer', 'pomoplus', 'alarm',
|
|
'rpnsci', 'calendar', 'torch', 'weather'
|
|
],
|
|
|
|
swipe: {
|
|
// 4 shortcuts to launch upon swiping:
|
|
// false = no shortcut
|
|
// '#LAUNCHER' = open the launcher
|
|
// any other string = name of app to open
|
|
up: 'messageui', // Swipe up or swipe down, due to limitation of event handler
|
|
down: 'messageui',
|
|
left: '#LAUNCHER',
|
|
right: '#LAUNCHER',
|
|
},
|
|
|
|
fastLoad: {
|
|
shortcuts: [
|
|
false, false, false, false,
|
|
false, false, false, false
|
|
],
|
|
swipe: {
|
|
up: false,
|
|
down: false,
|
|
left: false,
|
|
right: false
|
|
}
|
|
},
|
|
|
|
bar: {
|
|
enabledLocked: true, // Whether this bar is enabled when the watch is locked
|
|
enabledUnlocked: false, // Whether the bar is enabled when the watch is unlocked
|
|
type: 'split', // off = no bar, dayProgress = day progress bar, calendar = calendar bar, split = both
|
|
|
|
dayProgress: { // A progress bar representing how far through the day you are
|
|
color: [0, 0, 1], // The color of the bar
|
|
start: 700, // The time of day that the bar starts filling
|
|
end: 2200, // The time of day that the bar becomes full
|
|
reset: 300 // The time of day when the progress bar resets from full to empty
|
|
},
|
|
|
|
calendar: {
|
|
duration: 10800,
|
|
pipeColor: [1, 1, 1],
|
|
defaultColor: [0, 0, 1]
|
|
},
|
|
},
|
|
|
|
lowBattColor: {
|
|
// The text can change color to indicate that the battery is low
|
|
level: 20, // The percentage where this happens
|
|
color: [1, 0, 0] // The color that the text changes to
|
|
}
|
|
}
|
|
|
|
let storedConfig = storage.readJSON(SETTINGS_FILE, true) || {};
|
|
|
|
// Ugly slow workaround because object.constructor doesn't exist on Bangle
|
|
function isDictionary(object) {
|
|
return JSON.stringify(object)[0] == '{';
|
|
}
|
|
|
|
/** Merge two objects recursively. (Object.assign() cannot be used here because it is NOT recursive.)
|
|
* Any key that is in one object but not the other will be included as is.
|
|
* Any key that is in both objects, but whose value is not a dictionary in both objects, will have the version in overlay included.
|
|
* Any key that whose value is a dictionary in both properties will have its result be set to a recursive call to merge.
|
|
*/
|
|
function merge(overlay, base) {
|
|
let result = base;
|
|
|
|
for (objectKey in overlay) {
|
|
if (!Object.keys(base).includes(objectKey)) result[objectKey] = overlay[objectKey]; // If the key isn't there, add it
|
|
else if (isDictionary(base[objectKey]) && isDictionary(overlay[objectKey])) // If the key is a dictionary in both, do recursive call
|
|
result[objectKey] = merge(overlay[objectKey], base[objectKey]);
|
|
else result[objectKey] = overlay[objectKey]; // Otherwise, override
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
exports.getConfig = () => {
|
|
return merge(storedConfig, defaultConfig);
|
|
}; |