Fix edge-cases where an incorrect setter countdown could be displayed
This commit is contained in:
1 parent
67d6468c02
commit
26dc5f9505
4 files changed
+50
-24
No files matched your search
@@ -18,13 +18,10 @@ Trigalarm is meant to be adapted to your needs with as little confusion as possi
|
||||
- Punishes the user via mild electrocution if they...
|
||||
- ...take too long to respond to the first triangle
|
||||
- ...force quit the app by holding the back button (the app re-opens and sends a zap)
|
||||
|
||||
## Tips & Tricks
|
||||
- When you successfully disarm the alarm, you are prompted with the options to either exit and keep the same alarm time for tomorrow, or to select a new time. If choosing the latter, whatever time you select will assume you mean tomorrow. This avoids situations where you wake up at 6 on a Friday, set an alarm intended for 9 on Saturday, and end up with your wrist buzzing in three hours!
|
||||
- There is a "Reset Alarm" button in the phone-side settings to help if you make an unsolvable alarm configuration by mistake.
|
||||
|
||||
## Some Neat Stuff
|
||||
- Some of the alarm scheduling code was taken from [Gentle Wake](https://github.com/SeaPea/GentleWake). It seems trusted by the community, so... I stole it! The beauty of open source, no AI needed!
|
||||
- A custom font was made to satisfy the need for something that looks like LECO but is monospaced. The version I made contains only numbers, period, and colon, but if you want to build off of it, [it's public](https://git.wetfence.xyz/RandyTheSilly/pebble-misc/src/branch/main/fonts) and easy to modify!
|
||||
|
||||
## Future Goals (v2.1 and beyond)
|
||||
- Custom, self-hosted Pavlok API support (going to try some Bluetooth reverse engineering)
|
||||
+35
-6
@@ -65,6 +65,8 @@ static WakeupReason s_alarm_reason;
|
||||
static GColor s_setter_highlight_color;
|
||||
static uint8_t s_highlight_pos = 0;
|
||||
static bool s_skip_current_day = false;
|
||||
static bool s_skip_current_day_from_confirmation = false;
|
||||
static uint8_t s_skip_current_day_set_on_mday; // day the flag was set on
|
||||
//// alarm
|
||||
static uint8_t s_current_triangle_num;
|
||||
static uint8_t s_solution_indices[3];
|
||||
@@ -120,6 +122,15 @@ typedef enum {
|
||||
|
||||
static void push_setter_window();
|
||||
|
||||
static void set_skip_current_day(bool from_confirmation) {
|
||||
time_t now = time(NULL);
|
||||
struct tm now_tm = *localtime(&now);
|
||||
|
||||
s_skip_current_day = true;
|
||||
s_skip_current_day_from_confirmation = from_confirmation;
|
||||
s_skip_current_day_set_on_mday = now_tm.tm_mday;
|
||||
}
|
||||
|
||||
static void click_handler_push_setter(void *recognizer, void *ctx) {
|
||||
s_highlight_pos = 0;
|
||||
window_stack_pop_all(true);
|
||||
@@ -133,7 +144,7 @@ static void click_handler_disable_tutorial_and_push_setter(void *recognizer, voi
|
||||
}
|
||||
|
||||
static void click_handler_push_setter_skip_current_day(void *recognizer, void *ctx) {
|
||||
s_skip_current_day = true; // setting the next alarm should assume the user meant tomorrow
|
||||
set_skip_current_day(true); // setting the next alarm should assume the user meant tomorrow
|
||||
click_handler_push_setter(recognizer, ctx);
|
||||
}
|
||||
|
||||
@@ -245,13 +256,11 @@ static bool schedule_alarm(WakeupReason schedule_reason) {
|
||||
switch (schedule_reason) {
|
||||
case WAKE_ALARM: {
|
||||
target = compute_alarm_time(the_time.HourWIP, the_time.MinuteWIP);
|
||||
wakeup_cancel_all();
|
||||
status = wakeup_schedule_simple_robust(target, schedule_reason);
|
||||
break;
|
||||
}
|
||||
case WAKE_RECOVERY_ALARM:
|
||||
target = time(NULL) + 15;
|
||||
// no need to cancel alarms, as recovery alarms are short-lived and are expired by the time another is being scheduled
|
||||
status = wakeup_schedule_simple_robust(target, schedule_reason);
|
||||
}
|
||||
if (status < 0) {
|
||||
@@ -913,8 +922,13 @@ static void push_alarm_window() {
|
||||
////////////////////// SETTER //////////////////////
|
||||
|
||||
static void setter_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
||||
struct tm now_tm = *tick_time;
|
||||
// unset s_skip_current_day if the day changes while the setter is open
|
||||
if (s_skip_current_day && tick_time->tm_mday != s_skip_current_day_set_on_mday) {
|
||||
s_skip_current_day = false;
|
||||
s_skip_current_day_from_confirmation = false;
|
||||
}
|
||||
|
||||
struct tm now_tm = *tick_time;
|
||||
time_t now = mktime(&now_tm);
|
||||
time_t target = compute_alarm_time(the_time.HourSet, the_time.MinuteSet);
|
||||
|
||||
@@ -1001,6 +1015,11 @@ static void setter_down_click_handler(void *recognizer, void *ctx) {
|
||||
|
||||
static void setter_select_click_handler(void *recognizer, void *ctx) {
|
||||
if (s_highlight_pos == 2) {
|
||||
// do not skip a day if the setter was opened directly
|
||||
if (s_skip_current_day && !s_skip_current_day_from_confirmation) {
|
||||
s_skip_current_day = false;
|
||||
}
|
||||
|
||||
bool success = schedule_alarm(WAKE_ALARM);
|
||||
if (!success) {
|
||||
return; // early return to avoid indicating alarm was set when it was not
|
||||
@@ -1045,6 +1064,7 @@ static void live_wakeup_handler_for_setter(WakeupId id, int32_t reason) {
|
||||
|
||||
// reset values potentially set by prior alarm
|
||||
s_skip_current_day = false;
|
||||
s_skip_current_day_from_confirmation = false;
|
||||
s_selected_indices[0] = 9;
|
||||
s_selected_indices[1] = 9;
|
||||
s_selected_indices[2] = 9;
|
||||
@@ -1084,10 +1104,19 @@ static void setter_window_load() {
|
||||
text_layer_set_background_color(s_countdown_txt_layer, GColorClear);
|
||||
text_layer_set_font(s_countdown_txt_layer, s_font_lecoish_small);
|
||||
layer_add_child(window_layer, text_layer_get_layer(s_countdown_txt_layer));
|
||||
if (!s_skip_current_day) {
|
||||
WakeupId wakeup_id = persist_read_int(STORAGE_KEY_ALARM_WAKEUP_ID);
|
||||
if (wakeup_id > 0) {
|
||||
time_t now = time(NULL);
|
||||
time_t scheduled_time = now;
|
||||
bool scheduled = wakeup_query(wakeup_id, &scheduled_time);
|
||||
if (scheduled && (scheduled_time - now) > SECONDS_PER_DAY) {
|
||||
set_skip_current_day(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
update_countdown_display();
|
||||
|
||||
// progress
|
||||
|
||||
// highlighter
|
||||
s_setter_highlight_layer = layer_create(GRect(0, s_top_bar_grect.size.h, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT - (2 * s_top_bar_grect.size.h)));
|
||||
layer_set_update_proc(s_setter_highlight_layer, setter_highlight_layer_update_proc);
|
||||
|
||||
+13
-14
@@ -1,4 +1,5 @@
|
||||
#include "scheduler.h"
|
||||
#include "settings.h"
|
||||
#include <pebble.h>
|
||||
|
||||
struct TheTime the_time;
|
||||
@@ -16,26 +17,24 @@ static void glance_reload_callback(AppGlanceReloadSession *session, size_t limit
|
||||
app_glance_add_slice(session, slice);
|
||||
}
|
||||
|
||||
// Originally stolen from https://github.com/SeaPea/GentleWake (simplified by me for SDK 4.44+);
|
||||
// A slightly more robust wakeup scheduler that retries on errors
|
||||
WakeupId wakeup_schedule_simple_robust(time_t wakeup_time, WakeupReason wakeup_reason) {
|
||||
WakeupId result = 0;
|
||||
result = wakeup_schedule(wakeup_time, wakeup_reason, true);
|
||||
wakeup_cancel_all(); // only 1 wakeup should be scheduled for this app at any time
|
||||
WakeupId result = wakeup_schedule(wakeup_time, wakeup_reason, true);
|
||||
|
||||
if (result < 0) {
|
||||
// If result is negative, something went wrong, so make sure all wakeups for this app are cancelled and try again
|
||||
wakeup_cancel_all();
|
||||
result = wakeup_schedule(wakeup_time, wakeup_reason, true);
|
||||
|
||||
// As of SDK 4.44, E_RANGE result no longer needs handled, as it now only reports wakeups scheduled by THIS app;
|
||||
// we call wakeup_cancel_all() above, so E_RANGE will never be encountered
|
||||
}
|
||||
|
||||
if (result >= 0) {
|
||||
if (result >= 0) { // positive result code is a wakeup ID
|
||||
the_time.HourSet = the_time.HourWIP;
|
||||
the_time.MinuteSet = the_time.MinuteWIP;
|
||||
app_glance_reload(glance_reload_callback, (void *)(uintptr_t)wakeup_time);
|
||||
if (wakeup_reason == WAKE_ALARM) {
|
||||
// store wakeup ID for regular alarms so the setter can reference
|
||||
// it later to generate the initial countdown
|
||||
persist_write_int(STORAGE_KEY_ALARM_WAKEUP_ID, result);
|
||||
}
|
||||
}
|
||||
|
||||
// As of SDK 4.44, E_RANGE result no longer needs handled, as it now only reports wakeups scheduled by THIS app;
|
||||
// we call wakeup_cancel_all() above, so E_RANGE will never be encountered, thus any failure
|
||||
// that occurs here cannot be remedied, so we just return the result code.
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
#define STORAGE_KEY_ALARM_HOUR 0
|
||||
#define STORAGE_KEY_ALARM_MINUTE 1
|
||||
#define STORAGE_KEY_ALARM_REASON 2
|
||||
#define STORAGE_KEY_ALARM_WAKEUP_ID 3
|
||||
|
||||
typedef struct AppSettings {
|
||||
bool TutorialEnabled;
|
||||
|
||||
Reference in new issue
Block a user