this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

options

alice 03b66a63 61580d3f

+150 -15
+21
package-lock.json
··· 1 + { 2 + "name": "tidface", 3 + "version": "1.0.0", 4 + "lockfileVersion": 3, 5 + "requires": true, 6 + "packages": { 7 + "": { 8 + "name": "tidface", 9 + "version": "1.0.0", 10 + "dependencies": { 11 + "pebble-clay": "^1.0.4" 12 + } 13 + }, 14 + "node_modules/pebble-clay": { 15 + "version": "1.0.4", 16 + "resolved": "https://registry.npmjs.org/pebble-clay/-/pebble-clay-1.0.4.tgz", 17 + "integrity": "sha512-/rXxmltdW8JyohDzXINdea+d2wnFJVNFiTXfuZsKpySURZSCFMMucX9sZPZvbHnEA4xFINM4iicyhBbvY4ALfw==", 18 + "license": "MIT" 19 + } 20 + } 21 + }
+7 -3
package.json
··· 2 2 "name": "tidface", 3 3 "author": "aliceisjustplaying", 4 4 "version": "1.0.0", 5 - "keywords": ["pebble-app"], 5 + "keywords": [ 6 + "pebble-app" 7 + ], 6 8 "private": true, 7 - "dependencies": {}, 9 + "dependencies": { 10 + "pebble-clay": "^1.0.4" 11 + }, 8 12 "pebble": { 9 13 "displayName": "tidface", 10 14 "uuid": "d3486974-f487-4d30-b67f-9143c3ce7ab3", ··· 20 24 "watchface": true 21 25 }, 22 26 "messageKeys": [ 23 - "dummy" 27 + "timeAlignmentMode" 24 28 ], 25 29 "resources": { 26 30 "media": []
pebble_screenshot_2025-04-25_00-39-38.png

This is a binary file and will not be displayed.

pebble_screenshot_2025-04-25_00-39-55.png

This is a binary file and will not be displayed.

+1 -1
scripts/generateAirportTzList.ts
··· 465 465 const b2 = code.charCodeAt(2) - 65; 466 466 const bits = (b0 << 10) | (b1 << 5) | b2; 467 467 cContent += ` 0x${bits.toString(16)}, /* ${code} */\n`; 468 - } 468 + } 469 469 cContent += `};\n\n`; 470 470 471 471 // Count of bit-packed airport codes
+8 -7
src/c/clock_closest_airport_noon.h
··· 74 74 static inline void clock_closest_airport_noon_deinit(TextLayer *layer); 75 75 static inline void clock_closest_airport_noon_update(TextLayer *code_layer, 76 76 TextLayer *time_layer, 77 - time_t current_utc_t); 77 + time_t current_utc_t, 78 + long target_seconds_of_day); 78 79 // ------------------------------------------------------------------------- 79 80 80 81 // Internal constants / storage -------------------------------------------- 81 82 #define DAY_SECONDS (24 * 3600L) 82 - #define NOON_SECONDS (12 * 3600L) 83 83 84 84 // static char s_airport_noon_buffer[40]; // code + MM:SS 85 85 static time_t s_last_update_time = -1; ··· 98 98 return (now_utc >= tz->dst_start_utc || now_utc < tz->dst_end_utc); 99 99 } 100 100 101 - static inline void _airport_pick_new(time_t current_utc_t) { 101 + static inline void _airport_pick_new(time_t current_utc_t, long target_seconds_of_day) { 102 102 srand((unsigned int)current_utc_t); // stable randomness per eval moment 103 103 104 104 uint32_t utc_secs = current_utc_t % DAY_SECONDS; ··· 116 116 long local_secs = (long)utc_secs + (long)(offset_h * 3600.0f); 117 117 local_secs %= DAY_SECONDS; 118 118 if (local_secs < 0) local_secs += DAY_SECONDS; 119 - if (local_secs < NOON_SECONDS) continue; // hasn't reached noon yet 120 - long delta = local_secs - NOON_SECONDS; 119 + if (local_secs < target_seconds_of_day) continue; // hasn't reached target time yet 120 + long delta = local_secs - target_seconds_of_day; 121 121 if (delta < best_delta) { 122 122 best_delta = delta; 123 123 best_count = 0; ··· 179 179 180 180 static inline void clock_closest_airport_noon_update(TextLayer *code_layer, 181 181 TextLayer *time_layer, 182 - time_t current_utc_t) { 182 + time_t current_utc_t, 183 + long target_seconds_of_day) { 183 184 if (!code_layer || !time_layer) return; 184 185 185 186 // Skip redundant updates in the same second ··· 199 200 } 200 201 201 202 if (needs_eval) { 202 - _airport_pick_new(current_utc_t); 203 + _airport_pick_new(current_utc_t, target_seconds_of_day); 203 204 } 204 205 205 206 // Update text layers ---------------------------------------------------
+74 -4
src/c/watchface.c
··· 8 8 #include "clock_tid.h" 9 9 // #include "clock_decimal.h" 10 10 11 + // --- Clock Modules & Settings --- 12 + #define SETTINGS_KEY 1 13 + 14 + typedef enum { 15 + MODE_NOON = 0, 16 + MODE_5PM = 1 17 + } TargetTimeMode; 18 + 19 + typedef struct AppSettings { 20 + TargetTimeMode target_time_mode; 21 + } AppSettings; 22 + 23 + static AppSettings settings; 24 + 11 25 // --- Window and Layer Globals --- 12 26 static Window *s_main_window; 13 27 static TextLayer *s_airport_noon_code_layer; ··· 18 32 19 33 // --- Pebble Window Management --- 20 34 35 + // --- Settings Load/Save/Receive --- 36 + static void load_settings() { 37 + // Set default values 38 + settings.target_time_mode = MODE_NOON; 39 + // Read settings from persistent storage, if they exist 40 + persist_read_data(SETTINGS_KEY, &settings, sizeof(settings)); 41 + } 42 + 43 + static void save_settings() { 44 + persist_write_data(SETTINGS_KEY, &settings, sizeof(settings)); 45 + } 46 + 47 + static void inbox_received_handler(DictionaryIterator *iter, void *context) { 48 + APP_LOG(APP_LOG_LEVEL_INFO, "Inbox received!"); 49 + // Read timeAlignmentMode preference 50 + Tuple *target_time_mode_t = dict_find(iter, MESSAGE_KEY_timeAlignmentMode); 51 + if (target_time_mode_t) { 52 + APP_LOG(APP_LOG_LEVEL_INFO, "Found key timeAlignmentMode with value %d", (int)target_time_mode_t->value->int32); 53 + // Convert received ASCII value ('0' or '1') to enum 54 + int received_value = (int)target_time_mode_t->value->int32; 55 + if (received_value == 49) { // ASCII for '1' 56 + settings.target_time_mode = MODE_5PM; 57 + } else { // Default to Noon for '0' (ASCII 48) or unexpected values 58 + settings.target_time_mode = MODE_NOON; 59 + } 60 + APP_LOG(APP_LOG_LEVEL_INFO, "Setting mode to: %d", settings.target_time_mode); 61 + } else { 62 + APP_LOG(APP_LOG_LEVEL_WARNING, "Key timeAlignmentMode not found!"); 63 + } 64 + 65 + // Save the new settings 66 + save_settings(); 67 + 68 + // Potentially force an update if needed (e.g., re-pick airport) 69 + s_last_re_eval_time = -1; // Force re-evaluation on next tick 70 + } 71 + 21 72 // Handles updates from the TickTimerService 22 73 static void tick_handler(struct tm *tick_time, TimeUnits units_changed) { 23 74 time_t seconds; 24 75 uint16_t milliseconds; 25 76 time_ms(&seconds, &milliseconds); 77 + 78 + APP_LOG(APP_LOG_LEVEL_DEBUG, "Tick! Current mode: %d", settings.target_time_mode); 79 + // Determine target seconds based on setting 80 + long target_seconds = (settings.target_time_mode == MODE_5PM) ? (17 * 3600L) : (12 * 3600L); 81 + 26 82 // Hero: Closest Noon (update city and time layers) 27 - clock_closest_airport_noon_update(s_airport_noon_code_layer, s_airport_noon_time_layer, seconds); 83 + clock_closest_airport_noon_update(s_airport_noon_code_layer, s_airport_noon_time_layer, seconds, target_seconds); 84 + 28 85 // Update airport name below the code 29 86 text_layer_set_text(s_airport_noon_name_layer, s_selected_name); 30 87 // Footer: TID (larger) and Beat (smaller) ··· 87 144 static void init() { 88 145 srand(time(NULL)); 89 146 147 + // Load settings 148 + load_settings(); 149 + 90 150 // Create main Window element and assign to pointer 91 151 s_main_window = window_create(); 92 152 // Ensure text layers with clear background show up on white ··· 103 163 // Get initial time and update display immediately 104 164 time_t seconds; 105 165 uint16_t milliseconds; 106 - time_ms(&seconds, &milliseconds); // Call only once 107 - // Initial updates can be skipped if layers show placeholders, 108 - // tick_handler will update them shortly after load. 166 + time_ms(&seconds, &milliseconds); 167 + // Perform initial update after loading settings 168 + tick_handler(NULL, SECOND_UNIT); // Pass NULL tick_time as it's not used by our handler logic 109 169 110 170 // Register with TickTimerService to update every second 111 171 tick_timer_service_subscribe(SECOND_UNIT, tick_handler); 172 + 173 + // Register AppMessage handlers 174 + app_message_register_inbox_received(inbox_received_handler); 175 + // Open AppMessage with default inbox size from Clay docs 176 + AppMessageResult result = app_message_open(128, 0); // 128 inbox, 0 outbox (adjust if needed) 177 + if (result == APP_MSG_OK) { 178 + APP_LOG(APP_LOG_LEVEL_INFO, "AppMessage opened successfully!"); 179 + } else { 180 + APP_LOG(APP_LOG_LEVEL_ERROR, "Failed to open AppMessage: %d", result); 181 + } 112 182 } 113 183 114 184 static void deinit() {
+36
src/pkjs/config.js
··· 1 + module.exports = [ 2 + { 3 + type: "heading", 4 + defaultValue: "Tidface Configuration", 5 + }, 6 + { 7 + type: "text", 8 + defaultValue: "What should the clock be aligned to?", 9 + }, 10 + 11 + { 12 + type: "section", 13 + items: [ 14 + { 15 + type: "radiogroup", 16 + defaultValue: 0, 17 + label: "Time alignment mode", 18 + messageKey: "timeAlignmentMode", 19 + options: [ 20 + { 21 + label: "Noon", 22 + value: 0, 23 + }, 24 + { 25 + label: "It's 5 o'clock somewhere", 26 + value: 1, 27 + }, 28 + ], 29 + }, 30 + ], 31 + }, 32 + { 33 + type: "submit", 34 + defaultValue: "Save", 35 + }, 36 + ];
+3
src/pkjs/index.js
··· 1 + var Clay = require("pebble-clay"); 2 + var clayConfig = require("./config"); 3 + var clay = new Clay(clayConfig);