diff --git a/CHANGELOG.md b/CHANGELOG.md index dc5bad7..57de1c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ text to paste into the **Release notes** field when uploading the `.pbw` to the the build, so the portal does not auto-fill it). The store **Description** lives in [`PUBLISHING.md`](PUBLISHING.md). +## 0.0.3 + +- Fix settings being completely ignored on a real watch. 0.0.2 sent every + setting by name in the `pebblejs://close` payload; on a real watch that + payload is length-limited, so it was truncated, the JSON failed to parse, and + the save was silently dropped (it worked on the emulator, which uses a + different return path). Numeric settings now travel positionally (values only, + no key names), shrinking the payload ~3.6× so it always fits — while still + applying every shown value (WYSIWYG preserved). +- The loading splash now shows the real app version instead of a hard-coded + "3.0". + ## 0.0.2 - Settings are now WYSIWYG: saving the config page applies **every** value it diff --git a/PUBLISHING.md b/PUBLISHING.md index 184bd59..6ec5bd6 100644 --- a/PUBLISHING.md +++ b/PUBLISHING.md @@ -46,10 +46,15 @@ Rebble guides: **Keywords / tags:** calendar, weather, complications, date, week number, battery, moon phase, world time, minimal, localizable -## Release notes — v0.0.1 +## Release notes — v0.0.3 -> First public release. -> +> • Settings are now WYSIWYG and reliable: saving applies exactly what the +> configuration page shows (an earlier build could silently drop a save on a +> real watch). +> • Coloured weather icons on colour watches (basalt, emery) — sun amber, +> rain/snow blue, lightning amber, moon pale yellow — with a Default / Colour / +> Black & White choice under Weather → Icon style. +> • The loading splash shows the real app version. > • Configurable complication rows (status bar, above the time, above the > calendar) — one centred or two side by side per row. > • One shared, alphabetical menu for every slot, incl. watch/phone battery, diff --git a/README.md b/README.md index 0d546e9..00ae23b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ calendar below, and fully configurable complication rows you arrange yourself.** [![CI](https://github.com/eldios/TimelyNG/actions/workflows/ci.yml/badge.svg)](https://github.com/eldios/TimelyNG/actions/workflows/ci.yml) -![Version](https://img.shields.io/badge/version-0.0.1-blue) +![Version](https://img.shields.io/badge/version-0.0.3-blue) ![Platforms](https://img.shields.io/badge/Pebble-emery%20·%20flint%20·%20basalt%20·%20diorite-orange) ![Language](https://img.shields.io/badge/C-C99-555?logo=c) ![PebbleKit JS](https://img.shields.io/badge/config-PebbleKit%20JS-f5a623?logo=javascript&logoColor=white) diff --git a/package.json b/package.json index a757061..77db9f6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "TimelyNG", "author": "Emanuele 'Lele' Calo", - "version": "0.0.2", + "version": "0.0.3", "description": "A calendar watchface for Pebble: date, time and weather up top, a 3-week calendar below, and fully configurable complication rows. Appstore copy in PUBLISHING.md; release notes in CHANGELOG.md.", "private": true, "keywords": [ diff --git a/src/Timely.c b/src/Timely.c index da9f62d..365b6b1 100644 --- a/src/Timely.c +++ b/src/Timely.c @@ -12,7 +12,7 @@ #include "suntimes.h" #define DEBUGLOG 0 #define TRANSLOG 0 -#define CONFIG_VERSION "2.6" +#define CONFIG_VERSION "3.0" // config-protocol version (own sequence); major bump: the save wire format changed /* * If you fork this code and release the resulting app, please be considerate and change all the appropriate values in appinfo.json * diff --git a/src/js/app.js b/src/js/app.js index 170f95b..6e5cc57 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -1,5 +1,6 @@ var CONFIG_SPEC = require('./config'); var buildConfigPage = require('./configpage'); +var WIRE_KEYS = require('./wirekeys'); // decode the positional numeric settings (see webviewclosed) // The bundled SunCalc library (below) used to attach itself to `window`; under // the CommonJS bundler there is no global object, so it populates this @@ -312,18 +313,25 @@ V = waning crescent 0.25 + Pebble.addEventListener("webviewclosed", function (e) { if (!e || !e.response) { return; } // user cancelled - // The page sends every non-translation setting plus any changed translation - // string. Merge them into the stored settings so the config page keeps the - // full picture (incl. translations) and doesn't show untouched settings as - // reset on the next open. + // The page sends the numeric settings positionally in `n` (WIRE_KEYS order), + // plus the string settings and any changed translations by name. Expand `n` + // back to keys to rebuild the full desired state. (A legacy flat payload with + // no `n` is still accepted: its keys pass through unchanged.) var dict; try { dict = JSON.parse(decodeURIComponent(e.response)); } catch (err) { return; } + var full = {}; + if (dict.n && dict.n.length) { + for (var i = 0; i < WIRE_KEYS.length; i++) { full[WIRE_KEYS[i]] = dict.n[i]; } + delete dict.n; + } + for (var k in dict) { full[k] = dict[k]; } // strings, translations, or legacy flat keys + var stored = {}; try { stored = JSON.parse(localStorage.getItem("timely_settings") || "{}"); } catch (err) {} - for (var k in dict) { stored[k] = dict[k]; } + for (var sk in full) { stored[sk] = full[sk]; } localStorage.setItem("timely_settings", JSON.stringify(stored)); - Pebble.sendAppMessage(dict, + Pebble.sendAppMessage(full, function (e) { console.log("Delivered config with transactionId=" + e.data.transactionId); }, diff --git a/src/js/configpage.js b/src/js/configpage.js index 39c5ab0..1530e34 100644 --- a/src/js/configpage.js +++ b/src/js/configpage.js @@ -1,5 +1,7 @@ 'use strict'; +var WIRE_KEYS = require('./wirekeys'); // numeric settings sent positionally (see below) + // Builds the offline settings page as a self-contained HTML string from the // config spec. No external CSS/JS/host: app.js serves it via a data: URI, so it // works with no network. On submit the page redirects to `return_to` (provided @@ -197,6 +199,7 @@ function buildConfigPage(spec, current) { 'return m?decodeURIComponent(m[1]):d;}' + 'var RET=qp("return_to","pebblejs://close#");' + 'var BASELINE=' + JSON.stringify(baseline) + ';' + + 'var WK=' + JSON.stringify(WIRE_KEYS) + ';' + 'var LANGS=' + JSON.stringify(LANGS) + ';' + // Language selector: resolve the chosen code, fill the (hidden) translation // fields from the table, and toggle the Custom editor. @@ -239,14 +242,17 @@ function buildConfigPage(spec, current) { 'els=document.querySelectorAll("[data-key]");for(var i=0;i' + '' + diff --git a/src/js/wirekeys.js b/src/js/wirekeys.js new file mode 100644 index 0000000..e98eeda --- /dev/null +++ b/src/js/wirekeys.js @@ -0,0 +1,21 @@ +'use strict'; + +// Ordered list of the numeric (uint8 / int8) settings sent on EVERY save. They +// travel positionally — values only, no key names — so the whole desired state +// fits in the tiny pebblejs://close payload a real watch can carry (the verbose +// per-key JSON of the full state gets truncated by the phone and the save is +// silently lost). configpage.js encodes values in this order; app.js decodes +// them back to keys. This order IS the wire contract between the two: never +// reorder or remove an entry — only APPEND new numeric keys at the end. +// +// The two non-translation STRING settings (strftime_format, language) and any +// changed translation strings travel by name alongside the array; they are few +// and short, so they do not blow the payload. +module.exports = [ + 'theme', 'theme_mode', 'style_day_inv', 'style_grid', 'intl_fmt_date', + 'slot_stat_l', 'slot_stat_r', 'slot_ctr_l', 'slot_ctr_r', 'style_week', 'style_am_pm', + 'batt_style', 'intl_fmt_week', 'clock2_tz', 'intl_dowo', 'cal_week_pattern', + 'weather_fmt', 'weather_update', 'weather_icons', 'show_stat_bar', 'show_stat_batt', + 'vibe_pat_disconnect', 'vibe_pat_connect', 'debugging_on', 'debuglang_on', + 'vibe_days', 'vibe_hour', 'vibe_start', 'vibe_stop', 'dnd_noaccel', 'dnd_start', 'dnd_stop' +]; diff --git a/src/splash.c b/src/splash.c index 90655d9..3e3d031 100644 --- a/src/splash.c +++ b/src/splash.c @@ -2,6 +2,9 @@ #include "theme.h" #include "layout.h" +// Version shown on the loading splash. Keep in sync with package.json "version". +#define APP_VERSION "0.0.3" + static Layer *s_splash_layer; static void splash_render(Layer *me, GContext* ctx) { @@ -9,7 +12,7 @@ static void splash_render(Layer *me, GContext* ctx) { int w = layout_get().slot_bot.w; // full width: center the splash on any screen setColors(ctx); graphics_draw_text(ctx, "TimelyNG", fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD), GRect(0,0,w,36), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); - graphics_draw_text(ctx, "3.0", fonts_get_system_font(FONT_KEY_GOTHIC_28), GRect(0,32,w,36), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); + graphics_draw_text(ctx, APP_VERSION, fonts_get_system_font(FONT_KEY_GOTHIC_28), GRect(0,32,w,36), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); } void splash_create(Layer *parent, GRect frame) {