Make awareness alarm configurable and vastly more useful
This commit is contained in:
+4
-1
@@ -34,7 +34,10 @@
|
|||||||
"messageKeys": [
|
"messageKeys": [
|
||||||
"PKJS_READY",
|
"PKJS_READY",
|
||||||
"PKJS_PAVLOK_ENABLE",
|
"PKJS_PAVLOK_ENABLE",
|
||||||
"PKJS_PAVLOK_ZAP"
|
"PKJS_PAVLOK_ZAP",
|
||||||
|
"PKJS_AWARENESS_TIME_GAP",
|
||||||
|
"PKJS_AWARENESS_TIME_LIMIT",
|
||||||
|
"PKJS_AWARENESS_NUDGE_ENABLE"
|
||||||
],
|
],
|
||||||
"resources": {
|
"resources": {
|
||||||
"media": [
|
"media": [
|
||||||
|
|||||||
+93
-58
@@ -1,17 +1,21 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "triangles.h"
|
#include "triangles.h"
|
||||||
#include <pebble.h>
|
#include <pebble.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// settings
|
||||||
|
static AppSettings settings;
|
||||||
|
|
||||||
// layer-age
|
// layer-age
|
||||||
static Window *s_window;
|
static Window *s_window;
|
||||||
static Window *s_status_window;
|
static Window *s_status_window;
|
||||||
static Window *s_drop_window;
|
static Window *s_drop_window;
|
||||||
static Layer *s_top_bar_layer;
|
static Layer *s_top_bar_layer;
|
||||||
static Layer *s_bottom_bar_layer;
|
static Layer *s_bottom_bar_layer;
|
||||||
static TextLayer *s_counter_txt_layer;
|
static TextLayer *s_countdown_txt_layer;
|
||||||
static TextLayer *s_status_txt_layer;
|
static TextLayer *s_status_txt_layer;
|
||||||
//// setter
|
//// setter
|
||||||
static BitmapLayer *s_clock_bmp_layer;
|
static BitmapLayer *s_clock_bmp_layer;
|
||||||
@@ -56,7 +60,8 @@ static uint8_t s_highlight_pos = 0;
|
|||||||
static WakeupReason s_alarm_reason;
|
static WakeupReason s_alarm_reason;
|
||||||
static uint8_t s_solution_indices[3] = {8, 8, 8};
|
static uint8_t s_solution_indices[3] = {8, 8, 8};
|
||||||
static uint8_t s_selected_indices[3] = {9, 9, 9};
|
static uint8_t s_selected_indices[3] = {9, 9, 9};
|
||||||
static uint8_t s_stopwatch_time[2] = {0, 0};
|
static uint8_t s_awareness_countdown_int = 0;
|
||||||
|
static char s_awareness_countdown_buf[4];
|
||||||
static uint32_t s_vibe_segments[5];
|
static uint32_t s_vibe_segments[5];
|
||||||
static VibePattern s_vibe_pattern;
|
static VibePattern s_vibe_pattern;
|
||||||
|
|
||||||
@@ -85,7 +90,8 @@ static char *s_options_under[2];
|
|||||||
////////////////////// STATUS //////////////////////
|
////////////////////// STATUS //////////////////////
|
||||||
|
|
||||||
static void click_handler_disable_tutorial(void *recognizer, void *ctx) {
|
static void click_handler_disable_tutorial(void *recognizer, void *ctx) {
|
||||||
persist_write_bool(STORAGE_KEY_DISABLE_TUTORIAL, true);
|
settings.TutorialEnabled = false;
|
||||||
|
persist_write_data(STORAGE_KEY_SETTINGS, &settings, sizeof(settings));
|
||||||
window_stack_pop_all(true);
|
window_stack_pop_all(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +139,7 @@ static void status_window_load(StatusWindowPurpose purpose) {
|
|||||||
switch (purpose) {
|
switch (purpose) {
|
||||||
case STATUS_MAIN_TUTORIAL:
|
case STATUS_MAIN_TUTORIAL:
|
||||||
// don't disable ticks to ensure vibrations remain till the tutorial is closed
|
// don't disable ticks to ensure vibrations remain till the tutorial is closed
|
||||||
text_layer_set_text(s_status_txt_layer, "Congrats! To ensure you're awake, I'll re-open without vibrating in 9 minutes. Complete the equation within 60 seconds to disarm me. Take too long and I'll vibrate and re-schedule another alarm.\n\nPress SELECT to exit or BACK to disable this tutorial in the future (and exit).");
|
text_layer_set_text(s_status_txt_layer, "Correct! An awareness alarm is now being set. Solve it within the time limit to disarm Trigalarm.\n\nPress SELECT to exit or BACK to disable this tutorial in the future (and exit).");
|
||||||
window_set_click_config_provider(s_status_window, status_main_tutorial_click_config_provider);
|
window_set_click_config_provider(s_status_window, status_main_tutorial_click_config_provider);
|
||||||
break;
|
break;
|
||||||
case STATUS_CONFIRMATION: {
|
case STATUS_CONFIRMATION: {
|
||||||
@@ -173,21 +179,27 @@ static void push_status_window(StatusWindowPurpose purpose) {
|
|||||||
|
|
||||||
////////////////////// PKJS //////////////////////
|
////////////////////// PKJS //////////////////////
|
||||||
|
|
||||||
|
static void apply_uint8_from_tuple(DictionaryIterator *iter, uint32_t key, void *dest) {
|
||||||
|
Tuple *t = dict_find(iter, key);
|
||||||
|
if (!t)
|
||||||
|
return;
|
||||||
|
*(uint8_t *)dest = t->value->uint8;
|
||||||
|
}
|
||||||
|
|
||||||
static void inbox_received_handler(DictionaryIterator *iter, void *context) {
|
static void inbox_received_handler(DictionaryIterator *iter, void *context) {
|
||||||
Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_PKJS_READY);
|
Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_PKJS_READY);
|
||||||
if (ready_tuple) {
|
if (ready_tuple) {
|
||||||
return; // TODO use ready signal better
|
return; // TODO use ready signal better
|
||||||
}
|
}
|
||||||
|
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_PAVLOK_ENABLE, &settings.PavlokEnabled);
|
||||||
Tuple *clay_tuple = dict_find(iter, MESSAGE_KEY_PKJS_PAVLOK_ENABLE);
|
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_AWARENESS_TIME_GAP, &settings.AwarenessTimeGapMinutes);
|
||||||
if (clay_tuple) {
|
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_AWARENESS_TIME_LIMIT, &settings.AwarenessTimeLimitSeconds);
|
||||||
persist_write_bool(STORAGE_KEY_PAVLOK_ENABLED, clay_tuple->value->uint8);
|
apply_uint8_from_tuple(iter, MESSAGE_KEY_PKJS_AWARENESS_NUDGE_ENABLE, &settings.AwarenessNudgeEnabled);
|
||||||
return;
|
persist_write_data(STORAGE_KEY_SETTINGS, &settings, sizeof(settings));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_zap() {
|
static void send_zap() {
|
||||||
if (persist_read_bool(STORAGE_KEY_PAVLOK_ENABLED) == false) {
|
if (!settings.PavlokEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +228,7 @@ static bool schedule_alarm(WakeupReason schedule_reason) {
|
|||||||
status = wakeup_schedule_simple_robust(target, 15, schedule_reason);
|
status = wakeup_schedule_simple_robust(target, 15, schedule_reason);
|
||||||
break;
|
break;
|
||||||
case WAKE_AWARENESS_ALARM:
|
case WAKE_AWARENESS_ALARM:
|
||||||
target = time(NULL) + 9 * SECONDS_PER_MINUTE;
|
target = time(NULL) + settings.AwarenessTimeGapMinutes * SECONDS_PER_MINUTE;
|
||||||
wakeup_cancel_all();
|
wakeup_cancel_all();
|
||||||
status = wakeup_schedule_simple_robust(target, SECONDS_PER_MINUTE, schedule_reason);
|
status = wakeup_schedule_simple_robust(target, SECONDS_PER_MINUTE, schedule_reason);
|
||||||
break;
|
break;
|
||||||
@@ -239,7 +251,7 @@ static bool schedule_alarm(WakeupReason schedule_reason) {
|
|||||||
persist_write_int(STORAGE_KEY_ALARM_REASON, WAKE_MAIN_ALARM);
|
persist_write_int(STORAGE_KEY_ALARM_REASON, WAKE_MAIN_ALARM);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (s_alarm_reason != schedule_reason) {
|
if (persist_read_int(STORAGE_KEY_ALARM_REASON) != schedule_reason) {
|
||||||
persist_write_int(STORAGE_KEY_ALARM_REASON, schedule_reason);
|
persist_write_int(STORAGE_KEY_ALARM_REASON, schedule_reason);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -270,26 +282,20 @@ static void add_bar_layers_to_window(Layer *window_layer, bool small_top) {
|
|||||||
|
|
||||||
////////////////////// ALARM //////////////////////
|
////////////////////// ALARM //////////////////////
|
||||||
|
|
||||||
static void alarm_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
static void main_alarm_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
// update stopwatch
|
vibes_enqueue_custom_pattern(s_vibe_pattern);
|
||||||
if (s_stopwatch_time[1] == 59) {
|
}
|
||||||
s_stopwatch_time[1] = 0;
|
|
||||||
s_stopwatch_time[0]++;
|
static void awareness_alarm_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
send_zap();
|
if (s_awareness_countdown_int > 0) {
|
||||||
// fall back to main alarm and resume vibes
|
s_awareness_countdown_int--;
|
||||||
if (s_alarm_reason != WAKE_MAIN_ALARM) {
|
snprintf(s_awareness_countdown_buf, sizeof(s_awareness_countdown_buf), "%03u", s_awareness_countdown_int);
|
||||||
// this may be overwritten when the recovery alarm is set,
|
text_layer_set_text(s_countdown_txt_layer, s_awareness_countdown_buf);
|
||||||
// but it will still allow vibes to occur since the alarm reason
|
if (s_awareness_countdown_int == 0) {
|
||||||
// will not be awareness
|
send_zap(); // TODO implement repeat interval
|
||||||
s_alarm_reason = WAKE_MAIN_ALARM;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s_stopwatch_time[1]++;
|
// TODO flash countdown txt layer every second
|
||||||
}
|
|
||||||
static char s_stopwatch_buffer[9];
|
|
||||||
snprintf(s_stopwatch_buffer, sizeof(s_stopwatch_buffer), "%02u:%02u", s_stopwatch_time[0], s_stopwatch_time[1]);
|
|
||||||
text_layer_set_text(s_counter_txt_layer, s_stopwatch_buffer);
|
|
||||||
if (s_alarm_reason != WAKE_AWARENESS_ALARM) {
|
|
||||||
vibes_enqueue_custom_pattern(s_vibe_pattern);
|
vibes_enqueue_custom_pattern(s_vibe_pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -600,14 +606,18 @@ static void alarm_window_load() {
|
|||||||
s_drop_window,
|
s_drop_window,
|
||||||
(WindowHandlers){.load = drop_menu_window_load, .unload = drop_menu_window_unload});
|
(WindowHandlers){.load = drop_menu_window_load, .unload = drop_menu_window_unload});
|
||||||
|
|
||||||
// stopwatch
|
// countdown
|
||||||
s_counter_txt_layer = text_layer_create(GRect(0, (s_small_top_bar_height / 2) - PBL_IF_ROUND_ELSE(6, 10), PBL_DISPLAY_WIDTH, s_small_top_bar_height));
|
if (s_alarm_reason == WAKE_AWARENESS_ALARM) {
|
||||||
text_layer_set_background_color(s_counter_txt_layer, GColorClear);
|
s_countdown_txt_layer = text_layer_create(GRect(0, (s_small_top_bar_height / 2) - PBL_IF_ROUND_ELSE(6, 10), PBL_DISPLAY_WIDTH, s_small_top_bar_height));
|
||||||
text_layer_set_text_color(s_counter_txt_layer, GColorWhite);
|
text_layer_set_background_color(s_countdown_txt_layer, GColorClear);
|
||||||
text_layer_set_text_alignment(s_counter_txt_layer, GTextAlignmentCenter);
|
text_layer_set_text_color(s_countdown_txt_layer, GColorWhite);
|
||||||
text_layer_set_font(s_counter_txt_layer, s_font_lecoish_small);
|
text_layer_set_text_alignment(s_countdown_txt_layer, GTextAlignmentCenter);
|
||||||
text_layer_set_text(s_counter_txt_layer, "00:00");
|
text_layer_set_font(s_countdown_txt_layer, s_font_lecoish_small);
|
||||||
layer_add_child(window_layer, text_layer_get_layer(s_counter_txt_layer));
|
s_awareness_countdown_int = settings.AwarenessTimeLimitSeconds;
|
||||||
|
snprintf(s_awareness_countdown_buf, sizeof(s_awareness_countdown_buf), "%03u", s_awareness_countdown_int);
|
||||||
|
text_layer_set_text(s_countdown_txt_layer, s_awareness_countdown_buf);
|
||||||
|
layer_add_child(window_layer, text_layer_get_layer(s_countdown_txt_layer));
|
||||||
|
}
|
||||||
|
|
||||||
// setup vibes
|
// setup vibes
|
||||||
s_vibe_segments[0] = (uint32_t)(s_triangle_layer->angle_A * 2);
|
s_vibe_segments[0] = (uint32_t)(s_triangle_layer->angle_A * 2);
|
||||||
@@ -621,12 +631,18 @@ static void alarm_window_load() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
schedule_alarm(WAKE_RECOVERY_ALARM); // output is not captured, as it is not actionable
|
schedule_alarm(WAKE_RECOVERY_ALARM); // output is not captured, as it is not actionable
|
||||||
tick_timer_service_subscribe(SECOND_UNIT, alarm_seconds_handler);
|
if (s_alarm_reason == WAKE_AWARENESS_ALARM) {
|
||||||
|
tick_timer_service_subscribe(SECOND_UNIT, awareness_alarm_seconds_handler);
|
||||||
|
} else {
|
||||||
|
tick_timer_service_subscribe(SECOND_UNIT, main_alarm_seconds_handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alarm_window_unload() {
|
static void alarm_window_unload() {
|
||||||
tick_timer_service_unsubscribe();
|
tick_timer_service_unsubscribe();
|
||||||
text_layer_destroy(s_counter_txt_layer);
|
if (s_countdown_txt_layer != NULL) {
|
||||||
|
text_layer_destroy(s_countdown_txt_layer);
|
||||||
|
}
|
||||||
window_destroy(s_drop_window);
|
window_destroy(s_drop_window);
|
||||||
text_layer_destroy(s_side_a_txt_layer);
|
text_layer_destroy(s_side_a_txt_layer);
|
||||||
text_layer_destroy(s_side_b_txt_layer);
|
text_layer_destroy(s_side_b_txt_layer);
|
||||||
@@ -698,20 +714,19 @@ static void alarm_select_hold_handler(void *recognizer, void *ctx) {
|
|||||||
// no-longer-important recovery alarm
|
// no-longer-important recovery alarm
|
||||||
wakeup_service_subscribe(NULL);
|
wakeup_service_subscribe(NULL);
|
||||||
|
|
||||||
if (s_alarm_reason == WAKE_AWARENESS_ALARM) {
|
if (s_awareness_countdown_int > 0) {
|
||||||
// set main alarm if the awareness alarm was solved
|
// set main alarm if the awareness alarm was solved within time limit
|
||||||
tick_timer_service_unsubscribe(); // alarm is fully disarmed - stop vibes+countdown for confirmation window
|
tick_timer_service_unsubscribe(); // alarm is fully disarmed - prevent stimulus in confirmation window
|
||||||
if (schedule_alarm(WAKE_MAIN_ALARM)) {
|
if (schedule_alarm(WAKE_MAIN_ALARM)) {
|
||||||
push_status_window(STATUS_CONFIRMATION);
|
push_status_window(STATUS_CONFIRMATION);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// otherwise, set awareness alarm and exit
|
// otherwise, set awareness alarm and exit
|
||||||
if (schedule_alarm(WAKE_AWARENESS_ALARM)) {
|
if (schedule_alarm(WAKE_AWARENESS_ALARM)) {
|
||||||
if (persist_read_bool(STORAGE_KEY_DISABLE_TUTORIAL)) {
|
if (settings.TutorialEnabled && s_alarm_reason == WAKE_MAIN_ALARM) {
|
||||||
window_stack_pop_all(true);
|
|
||||||
} else {
|
|
||||||
// show tutorial if it has not yet been disabled
|
|
||||||
push_status_window(STATUS_MAIN_TUTORIAL);
|
push_status_window(STATUS_MAIN_TUTORIAL);
|
||||||
|
} else {
|
||||||
|
window_stack_pop_all(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -759,7 +774,7 @@ static void setter_seconds_handler(struct tm *tick_time, TimeUnits units_changed
|
|||||||
|
|
||||||
static char s_countdown_buffer[12];
|
static char s_countdown_buffer[12];
|
||||||
snprintf(s_countdown_buffer, sizeof(s_countdown_buffer), "%02u:%02u:%02u", hours, minutes, seconds);
|
snprintf(s_countdown_buffer, sizeof(s_countdown_buffer), "%02u:%02u:%02u", hours, minutes, seconds);
|
||||||
text_layer_set_text(s_counter_txt_layer, s_countdown_buffer);
|
text_layer_set_text(s_countdown_txt_layer, s_countdown_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_countdown_display() {
|
static void update_countdown_display() {
|
||||||
@@ -909,12 +924,12 @@ static void setter_window_load() {
|
|||||||
layer_add_child(window_layer, bitmap_layer_get_layer(s_check_bmp_layer));
|
layer_add_child(window_layer, bitmap_layer_get_layer(s_check_bmp_layer));
|
||||||
|
|
||||||
// countdown
|
// countdown
|
||||||
s_counter_txt_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 43), (s_top_bar_grect.size.h / 2) + PBL_IF_ROUND_ELSE(10, -10), PBL_IF_ROUND_ELSE(s_top_bar_grect.size.w, s_top_bar_grect.size.w - 39), 32));
|
s_countdown_txt_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 43), (s_top_bar_grect.size.h / 2) + PBL_IF_ROUND_ELSE(10, -10), PBL_IF_ROUND_ELSE(s_top_bar_grect.size.w, s_top_bar_grect.size.w - 39), 32));
|
||||||
text_layer_set_text_alignment(s_counter_txt_layer, GTextAlignmentCenter);
|
text_layer_set_text_alignment(s_countdown_txt_layer, GTextAlignmentCenter);
|
||||||
text_layer_set_text_color(s_counter_txt_layer, GColorWhite);
|
text_layer_set_text_color(s_countdown_txt_layer, GColorWhite);
|
||||||
text_layer_set_background_color(s_counter_txt_layer, GColorClear);
|
text_layer_set_background_color(s_countdown_txt_layer, GColorClear);
|
||||||
text_layer_set_font(s_counter_txt_layer, s_font_lecoish_small);
|
text_layer_set_font(s_countdown_txt_layer, s_font_lecoish_small);
|
||||||
layer_add_child(window_layer, text_layer_get_layer(s_counter_txt_layer));
|
layer_add_child(window_layer, text_layer_get_layer(s_countdown_txt_layer));
|
||||||
update_countdown_display();
|
update_countdown_display();
|
||||||
|
|
||||||
// highlighter
|
// highlighter
|
||||||
@@ -938,7 +953,7 @@ static void setter_window_unload() {
|
|||||||
tick_timer_service_unsubscribe();
|
tick_timer_service_unsubscribe();
|
||||||
text_layer_destroy(s_setter_txt_layer);
|
text_layer_destroy(s_setter_txt_layer);
|
||||||
layer_destroy(s_setter_highlight_layer);
|
layer_destroy(s_setter_highlight_layer);
|
||||||
text_layer_destroy(s_counter_txt_layer);
|
text_layer_destroy(s_countdown_txt_layer);
|
||||||
bitmap_layer_destroy(s_check_bmp_layer);
|
bitmap_layer_destroy(s_check_bmp_layer);
|
||||||
bitmap_layer_destroy(s_clock_bmp_layer);
|
bitmap_layer_destroy(s_clock_bmp_layer);
|
||||||
gbitmap_destroy(s_check_bmp);
|
gbitmap_destroy(s_check_bmp);
|
||||||
@@ -964,15 +979,35 @@ static void init() {
|
|||||||
the_time.HourSet = the_time.HourWIP;
|
the_time.HourSet = the_time.HourWIP;
|
||||||
the_time.MinuteSet = the_time.MinuteWIP;
|
the_time.MinuteSet = the_time.MinuteWIP;
|
||||||
|
|
||||||
// initialize pkjs TODO maybe only do in alarm mode?
|
// initialize pkjs
|
||||||
app_message_register_inbox_received(inbox_received_handler);
|
app_message_register_inbox_received(inbox_received_handler);
|
||||||
app_message_open(64, 64); // TODO tighten sizes
|
app_message_open(64, 64); // TODO tighten sizes
|
||||||
|
|
||||||
|
// load settings from persist (or set defaults if not present)
|
||||||
|
if (persist_exists(STORAGE_KEY_SETTINGS)) {
|
||||||
|
persist_read_data(STORAGE_KEY_SETTINGS, &settings, sizeof(settings));
|
||||||
|
} else {
|
||||||
|
settings.TutorialEnabled = true;
|
||||||
|
settings.PavlokEnabled = false;
|
||||||
|
settings.AwarenessTimeGapMinutes = 9;
|
||||||
|
settings.AwarenessTimeLimitSeconds = 30;
|
||||||
|
settings.AwarenessNudgeEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
s_alarm_reason = persist_read_int(STORAGE_KEY_ALARM_REASON);
|
s_alarm_reason = persist_read_int(STORAGE_KEY_ALARM_REASON);
|
||||||
switch (launch_reason()) {
|
switch (launch_reason()) {
|
||||||
case APP_LAUNCH_WAKEUP:
|
case APP_LAUNCH_WAKEUP:
|
||||||
if (s_alarm_reason == WAKE_RECOVERY_ALARM) {
|
switch (s_alarm_reason) {
|
||||||
|
case WAKE_RECOVERY_ALARM:
|
||||||
send_zap();
|
send_zap();
|
||||||
|
break;
|
||||||
|
case WAKE_AWARENESS_ALARM:
|
||||||
|
if (settings.AwarenessNudgeEnabled) {
|
||||||
|
vibes_short_pulse();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
push_alarm_window();
|
push_alarm_window();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define STORAGE_KEY_ALARM_REASON 10 // BUMP ON UPDATES TO PREVENT USERS GETTING STUCK W/O ALARM
|
|
||||||
#define STORAGE_KEY_ALARM_HOUR 0
|
|
||||||
#define STORAGE_KEY_ALARM_MINUTE 1
|
|
||||||
#define STORAGE_KEY_DISABLE_TUTORIAL 2
|
|
||||||
#define STORAGE_KEY_PAVLOK_ENABLED 3
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
STATUS_MAIN_TUTORIAL = 0,
|
STATUS_MAIN_TUTORIAL = 0,
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// BUMP ON UPDATES
|
||||||
|
#define STORAGE_KEY_SETTINGS 50
|
||||||
|
#define STORAGE_KEY_ALARM_REASON 100
|
||||||
|
|
||||||
|
#define STORAGE_KEY_ALARM_HOUR 0
|
||||||
|
#define STORAGE_KEY_ALARM_MINUTE 1
|
||||||
|
|
||||||
|
typedef struct AppSettings {
|
||||||
|
bool TutorialEnabled;
|
||||||
|
bool PavlokEnabled;
|
||||||
|
uint8_t AwarenessTimeGapMinutes;
|
||||||
|
uint8_t AwarenessTimeLimitSeconds;
|
||||||
|
uint8_t AwarenessNudgeEnabled;
|
||||||
|
} __attribute__((__packed__)) AppSettings;
|
||||||
|
|
||||||
|
_Static_assert(sizeof(AppSettings) <= 256, "AppSettings exceeds Pebble 256-byte persist limit!");
|
||||||
+39
-4
@@ -28,10 +28,10 @@ module.exports = [
|
|||||||
"id": "pavlok_zap_intensity",
|
"id": "pavlok_zap_intensity",
|
||||||
"type": "slider",
|
"type": "slider",
|
||||||
"messageKey": "PKJS_PAVLOK_ZAP_INTENSITY",
|
"messageKey": "PKJS_PAVLOK_ZAP_INTENSITY",
|
||||||
defaultValue: 30,
|
"defaultValue": 30,
|
||||||
min: 5,
|
"min": 5,
|
||||||
max: 100,
|
"max": 100,
|
||||||
step: 5,
|
"step": 5,
|
||||||
"label": "Zap Intensity"
|
"label": "Zap Intensity"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -42,6 +42,41 @@ module.exports = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "section",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "heading",
|
||||||
|
"size": 3,
|
||||||
|
"defaultValue": "Awareness Alarm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "awareness_time_gap",
|
||||||
|
"type": "slider",
|
||||||
|
"messageKey": "PKJS_AWARENESS_TIME_GAP",
|
||||||
|
"defaultValue": 9,
|
||||||
|
"min": 1,
|
||||||
|
"max": 30,
|
||||||
|
"label": "Gap From Main Alarm (Minutes)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "awareness_time_limit",
|
||||||
|
"type": "slider",
|
||||||
|
"messageKey": "PKJS_AWARENESS_TIME_LIMIT",
|
||||||
|
"defaultValue": 30,
|
||||||
|
"min": 3,
|
||||||
|
"max": 120,
|
||||||
|
"label": "Time Limit (Seconds)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "awareness_nudge_enable",
|
||||||
|
"type": "toggle",
|
||||||
|
"messageKey": "PKJS_AWARENESS_NUDGE_ENABLE",
|
||||||
|
"defaultValue": true,
|
||||||
|
"label": "Awareness Nudge"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "submit",
|
"type": "submit",
|
||||||
"defaultValue": "Save Settings"
|
"defaultValue": "Save Settings"
|
||||||
|
|||||||
Reference in New Issue
Block a user