From 207905bdbcbedeef9f1d9cf02a2a12b28e43f693 Mon Sep 17 00:00:00 2001 From: Aaron Tan Date: Sat, 23 Dec 2017 18:49:57 -0500 Subject: [PATCH] Fixes for offline achievement syncing Fixed a bug related to breathing stats and streaks being lost if watch was not connected to phone. --- src/c/achievement.c | 1 - src/c/breathe_window.c | 43 ++++++++++++++++++++++++++---------------- src/c/data.c | 24 +++++++++++------------ src/c/localize.c | 12 ++++++------ src/c/main.c | 8 ++++---- src/c/settings_menu.c | 2 +- src/pkjs/config-de.js | 2 +- src/pkjs/config-es.js | 2 +- src/pkjs/config-fr.js | 2 +- src/pkjs/config.js | 2 +- 10 files changed, 54 insertions(+), 44 deletions(-) diff --git a/src/c/achievement.c b/src/c/achievement.c index e954dc8..90e8081 100644 --- a/src/c/achievement.c +++ b/src/c/achievement.c @@ -29,7 +29,6 @@ void achievement_init() { void achievement_save_achievements() { persist_write_data(ACHIEVEMENT_KEY, &achievements, sizeof(achievements)); persist_write_int(ACHIEVEMENT_VERSION_KEY, 1); - persist_write_bool(ACHIEVEMENT_OFFLINE_KEY, connection_service_peek_pebble_app_connection()); } // Getters and setters for each achievement in the AchievementList Struct diff --git a/src/c/breathe_window.c b/src/c/breathe_window.c index 31694e8..1acd472 100644 --- a/src/c/breathe_window.c +++ b/src/c/breathe_window.c @@ -140,8 +140,6 @@ static void animation_end_callback(void *data) { s_animating = false; s_main_done = true; - snprintf(s_greet_text, sizeof(s_greet_text), "%s", localize_get_greet_text()); - // If the user breathes during passage from one day to another (i.e. 12AM) then set number of breaths to 0 snprintf(s_end_time, sizeof(s_end_time), "%s", data_get_date_today()); @@ -151,19 +149,23 @@ static void animation_end_callback(void *data) { // Add number of minutes breathed s_min_breathed_today += s_min_to_breathe; + // Write last duration data for App Glance + data_write_last_duration_data(s_min_to_breathe); + // Achievements #if !PBL_PLATFORM_APLITE + + // Add the minutes breathed to the total number of minutes breathed + data_set_total_minutes_breathed(data_get_total_minutes_breathed() + s_min_to_breathe); + data_calculate_streak_length(); // Check whether it's the longest streak and save if it is if (data_get_longest_streak() < data_get_streak_length()) { data_set_longest_streak(data_get_streak_length()); } - // Add the minutes breathed to the total number of minutes breathed - data_set_total_minutes_breathed(data_get_total_minutes_breathed() + s_min_to_breathe); - // String to hold the description - char * description = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@"; + char* description = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@"; // Show achievements for 5, 8, and 10 minutes breathed in this session if achievements are enabled switch (s_min_to_breathe) { @@ -313,27 +315,36 @@ static void animation_end_callback(void *data) { } break; } - - achievement_send_achievements(); #endif - } else if (complete == 1) { // The user interrupted their session, so only add what was breathed before aborting + } else if (strcmp(s_start_time, s_end_time) == 0 && complete == 1) { // The user interrupted their session, so only add what was breathed before aborting s_min_breathed_today += floor((time(NULL) - s_start_stamp) / 60); + if (floor((time(NULL) - s_start_stamp) / 60) >= 1) { + data_write_last_duration_data(floor((time(NULL) - s_start_stamp) / 60)); + } + #if !PBL_PLATFORM_APLITE + data_set_total_minutes_breathed(data_get_total_minutes_breathed() + floor((time(NULL) - s_start_stamp) / 60)); + #endif } else { // Not on the same day, so set number to zero s_min_breathed_today = 0; } - // Display minutes breathed today + // Display top and bottom text + snprintf(s_greet_text, sizeof(s_greet_text), "%s", localize_get_greet_text()); snprintf(s_min_today, sizeof(s_min_today), localize_get_min_breathed_today_text(), s_min_breathed_today); // Persist the number of minutes breathed in total today data_write_breathe_persist_data(s_min_breathed_today); data_write_date_persist_data(); - if (complete != 1) { - // Persist the duration of minutes if user didn't interrupt their session - data_write_last_duration_data(s_min_to_breathe); + // Set offline flag for AppMessage + #if !PBL_PLATFORM_APLITE + if (connection_service_peek_pebble_app_connection()) { + achievement_send_achievements(); + } else { + persist_write_bool(ACHIEVEMENT_OFFLINE_KEY, connection_service_peek_pebble_app_connection()); } + #endif // Sets different number of digits for one digit or two digits if (s_min_to_breathe == 10) { @@ -368,7 +379,7 @@ static void main_animation_end(void *data) { .update = radius_expand_update }; - int complete = (int)data; // Coerce data into int + int complete = (int)data; // Cast data into int if (complete == 0) { // Sets duration of animation @@ -555,7 +566,7 @@ static void main_animation_callback () { if (settings_get_heartRateVariation() && data_get_current_heart_rate() != 0) { int new_duration = settings_get_breathDuration(); if (new_duration > s_breath_duration) { - APP_LOG(APP_LOG_LEVEL_DEBUG, "Old duration %d, new %d", s_breath_duration, new_duration); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "Old duration %d, new %d", s_breath_duration, new_duration); s_breath_duration = new_duration; } } else { @@ -872,5 +883,5 @@ void breathe_window_push(int min) { // Show window on the watch, with animated = true window_stack_push(s_main_window, true); - APP_LOG(APP_LOG_LEVEL_DEBUG, "Heap free is %d after launching the breathe window.", (int)heap_bytes_free()); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "Heap free is %d after launching the breathe window.", (int)heap_bytes_free()); } \ No newline at end of file diff --git a/src/c/data.c b/src/c/data.c index f167804..fca527a 100644 --- a/src/c/data.c +++ b/src/c/data.c @@ -82,14 +82,14 @@ char *data_get_date_today() { struct tm *tick_time = localtime(&temp); static char date_buffer[11]; strftime(date_buffer, sizeof(date_buffer), "%F", tick_time); - APP_LOG(APP_LOG_LEVEL_DEBUG, "The date today is %s", date_buffer); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The date today is %s", date_buffer); return date_buffer; } // Writes the number of minutes breathed today to persistent storage void data_write_breathe_persist_data(int min_breathed_today){ persist_write_int(MIN_BREATHED_TODAY_KEY, min_breathed_today); - APP_LOG(APP_LOG_LEVEL_DEBUG, "The minutes breathed today are: %d", min_breathed_today); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The minutes breathed today are: %d", min_breathed_today); } // Stores the date associated with the minutes of breathing done @@ -135,9 +135,9 @@ int data_read_last_duration_data() { int last_duration = 0; if (persist_exists(LAST_DURATION_KEY)) { last_duration = persist_read_int(LAST_DURATION_KEY); - APP_LOG(APP_LOG_LEVEL_DEBUG, "The last duration was %d.", last_duration); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The last duration was %d.", last_duration); } else { - APP_LOG(APP_LOG_LEVEL_DEBUG, "User has not breathed before; created data."); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "User has not breathed before; created data."); data_write_last_duration_data(last_duration); } return last_duration; @@ -178,7 +178,7 @@ int data_get_today_epoch_time() { // Store today's date as the date for streak calculation as struct tm void data_set_streak_date_persist_data() { - APP_LOG(APP_LOG_LEVEL_DEBUG, "The set now time is %d.", data_get_today_epoch_time()); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The set now time is %d.", data_get_today_epoch_time()); persist_write_int(STREAK_DATE_KEY, data_get_today_epoch_time()); } @@ -210,7 +210,7 @@ static int data_calculate_time_difference() { int data_get_streak_length() { // Get the last date and convert to time_t to use with difftime // By default, last date is today's date with year set to 1900. - APP_LOG(APP_LOG_LEVEL_DEBUG, "The last time breathed was %d, and the difftime is %d.", data_get_streak_date_persist_data(), data_calculate_time_difference()); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The last time breathed was %d, and the difftime is %d.", data_get_streak_date_persist_data(), data_calculate_time_difference()); if (!persist_exists(STREAK_LENGTH_KEY) || ((data_calculate_time_difference() > SECONDS_PER_DAY) && data_get_streak_date_persist_data() != 631170000)) { // There is no streak in persist, or the length of time since the last time breathed is more than one day @@ -227,25 +227,25 @@ static void data_set_streak_length(int value) { // Returns how long the streak is continued void data_calculate_streak_length() { - APP_LOG(APP_LOG_LEVEL_DEBUG, "Streak length is being calculated!"); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "Streak length is being calculated!"); if (data_get_streak_date_persist_data() == 631170000) { // This means that the user has not breathed with the app before (since the timestamp is 1900-01-01) - APP_LOG(APP_LOG_LEVEL_DEBUG, "The user has breathed for the first time and the streak is 1 day."); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The user has breathed for the first time and the streak is 1 day."); data_set_streak_length(1); } else if (data_calculate_time_difference() > SECONDS_PER_DAY) { // difftime returns the difference between the two dates in seconds data_set_streak_length(1); - APP_LOG(APP_LOG_LEVEL_DEBUG, "The streak is 1 day because more than 1 has passed."); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The streak is 1 day because more than 1 has passed."); // This means that it's been more than a day; so streak is one day } else if (data_calculate_time_difference() == 0) { // This means that the user has breathed again on the same day and it's not the first time they've breathed with the app; no change in streak length } else { - APP_LOG(APP_LOG_LEVEL_DEBUG, "Streak exists and it's the first time they've breathed today."); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "Streak exists and it's the first time they've breathed today."); data_set_streak_length(data_get_streak_length() + 1); // Streak is whatever the last streak is, plus one } data_set_streak_date_persist_data(); - APP_LOG(APP_LOG_LEVEL_DEBUG, "The streak is %d.", data_get_streak_length()); - APP_LOG(APP_LOG_LEVEL_DEBUG, "Finished calculating streak length"); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The streak is %d.", data_get_streak_length()); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "Finished calculating streak length"); } // Returns a string with correctly formatted streak text diff --git a/src/c/localize.c b/src/c/localize.c index f7c5138..514126f 100644 --- a/src/c/localize.c +++ b/src/c/localize.c @@ -312,12 +312,12 @@ char* localize_get_greet_text() { char* localize_get_top_text(int random_number) { char*strings[9] = {"TAKE A MOMENT;", "BE STILL;", "CLEAR YOUR MIND;", "EMPTY YOUR THOUGHTS;", "BE CALM;", "THINK NOTHING;", "RELAX;", "CHILL FOR A SEC;", "SPACE OUT;"}; if (strncmp(localize_get_locale(), "fr", 2) == 0) { - char*french_strings[9] = {"PRENEZ UN MOMENT;", "RÉFLECHISSEZ;", "VIDEZ VOTRE ESPRIT;", "NE PENSEZ À RIEN;", "SOYEZ CALME;", "CONCENTREZ;", "RELAXEZ;", "NE VOUS INQUIETEZ PAS;", "DONNEZ-VOUS DE L'ESPACE;"}; + char*french_strings[9] = {"PRENEZ UN MOMENT;", "RÉFLECHISSEZ;", "OUVREZ VOTRE ESPRIT;", "NE PENSEZ À RIEN;", "SOYEZ CALME;", "CONCENTREZ;", "RELAXEZ;", "NE VOUS INQUIETEZ PAS;", "DONNEZ-VOUS DE L'ESPACE;"}; for (int i = 0; i <= 8; i++) { strings[i] = french_strings[i]; } } else if (strncmp(localize_get_locale(), "es", 2) == 0) { - char*spanish_strings[9] = {"TÓMATE UN TIEMPO;", "NO TE MUEVAS;", "ACLARA TU MENTE;", "NO PIENSA A NADA;", "SÉ CALMO;", "CONCÉNTRATE;", "RELÁJATE;", "NO TE PREOCUPES;", "TOMA UN MOMENTO;"}; + char*spanish_strings[9] = {"TÓMATE EL TIEMPO;", "NO TE MUEVAS;", "DESPÉJATE;", "NO PIENSA A NADA;", "TRANQUILÍZATE;", "CONCÉNTRATE;", "RELÁJATE;", "NO TE PREOCUPES;", "TOMA UN MOMENTO;"}; for (int i = 0; i <= 8; i++) { strings[i] = spanish_strings[i]; } @@ -1239,9 +1239,9 @@ char* localize_get_credits_row_title() { char* localize_get_new_version_title() { if (strncmp(localize_get_locale(), "es", 2) == 0) { - return "¡Versión 2.51!"; + return "¡Versión 2.52!"; } else { - return "Version 2.51!"; + return "Version 2.52!"; } } @@ -1261,7 +1261,7 @@ char* localize_get_credits_row_title() { if (strncmp(localize_get_locale(), "fr", 2) == 0) { return "NOUVEAUTÉS:\n\n• Vos succès sont maintenant copiés sur votre célullaire, et se restaurent automatiquement si vous supprimez puis réinstallez cette app.\n• Le montant minimum de respirations par minute a diminué à 2.\n• Si vous voulez revoir ces notes, sélectionnez la version dans le menu des paramètres sur votre montre.\n• Corrigé plusieurs plantages.\n\nLaissez un \u2764 sur l'App Store si vous aimez cette app!"; } else if (strncmp(localize_get_locale(), "es", 2) == 0) { - return "NUEVO:\n\n• Ahora se realiza una copia de seguridad de todos tus logros, y estos se restauran automáticamente si eliminas y luego reinstalas esta app.\n• El número mínimo de respiraciones por minuto ha bajado a 2.\n• Si quieres ver de nuevo estas notas, selecciona el número de versión en el menú de ajustes en tu reloj.\n• Varios fallos de programa fueron eliminados.\n\n¡Da un \u2764 en el App Store si te gusta esta app!"; + return "NUEVO:\n\n• Ahora se realiza una copia de seguridad de todos tus logros, y estos se restauran automáticamente si eliminas y luego reinstalas esta app.\n• El número mínimo de respiraciones por minuto ha bajado a 2.\n• Si quieres ver de nuevo estas notas, selecciona el número de versión en el menú de ajustes en tu reloj.\n• Varios fallos de programa fueron eliminados.\n\n¡Da un \u2764 en el App Store si a tí te gusta esta app!"; } else if (strncmp(localize_get_locale(), "de", 2) == 0) { return "NEU:\n\n• Ihre Erfolge werden nun auf dem Handy gespeichert, sodass sie bei einer Neuinstallation erhalten bleiben.\n• Die Anzahl Atemzüge pro Minute kann jetzt minimal 2 sein\n• Die Änderungen können erneut eingesehen werden, wenn Sie die Versionsnummer in den Einstellungen auf der Uhr anwählen\n• Mehrere Crashes und Speicherlecks behoben, darunter einer nach einer Erinnerung\n• Hinterlassen Sie ein \u2764 im App Store, wenn Ihnen diese App gefällt!"; } else { @@ -1273,7 +1273,7 @@ char* localize_get_credits_row_title() { if (strncmp(localize_get_locale(), "fr", 2) == 0) { return "Prenez un moment pour respirer.\n\nRESPIREZ.\nChoississez la durée de votre session de respiration avec les boutons haut et bas. Quand vous êtes prêt à commencer, appuyez le bouton du milieu.\n\nPERSONNALISEZ.\nChangez vos paramètres directement sur votre montre ou sur votre céllulaire! Appuyez longuement sur le bouton haut pour les changer sur votre montre.\n\nACHEVEZ.\nAu fur et à mesure que vous utilisez la app, vous gagnerez des succès! Admirez-les en appuyant longuement sur le bouton bas."; } else if (strncmp(localize_get_locale(), "es", 2) == 0) { - return "Tómate un momento a respirar.\n\nRESPIRA.\nEscoge cuántos minutes quieres que dure la sesión con unas pulsaciones de los botónes arriba y abajo. Cuando estés listo a comenzar, presiona el botón central.\n\nPERSONALIZA.\nCambia los ajustes en tu reloj o en tu móvil. ¡Con una pulsación larga del botón arriba se pueden cambiar ajustes en tu reloj!\n\nALCANZA.\n¡Con la respiración regular se puede ganar logros! Se puede verlos con una pulsación larga del botón abajo."; + return "Tómate un momento para respirar.\n\nRESPIRA.\nEscoge cuántos minutes quieres que dure la sesión con pulsaciones de los botónes arriba y abajo. Cuando estés listo para comenzar, presiona el botón central.\n\nPERSONALIZA.\nCambia los ajustes en tu reloj o en tu móvil. Con una pulsación larga del botón arriba puedes cambiar ajustes en tu reloj.\n\nALCANZA.\n¡Con la respiración regular ganarás logros! Se puede verlos con una pulsación larga del botón abajo."; } else if (strncmp(localize_get_locale(), "de", 2) == 0) { return "Ein Moment zum Durchatmen.\n\nBREATHE.\nIm Hauptmenü können Sie die Dauer der Atemübung mit dem oberen und dem unteren Knopf. Starten Sie die Übung mit dem mittleren Knopf.\nSie können Einstellungen auf dem Telefon und auf der Uhr vornehmnen. Drücken Sie den oberen Knopf lange, um die Einstellungen auf der Uhr zu öffnen.\n\nERFOLGE.\nWenn Sie Übungen machen, können Sie Erfolge erreichen und Statistiken sehen! Drücken und halten Sie den unteren Knopf um zu sehen, was Sie freigeschaltet haben."; } else { diff --git a/src/c/main.c b/src/c/main.c index 4b9d563..6766559 100644 --- a/src/c/main.c +++ b/src/c/main.c @@ -45,7 +45,7 @@ static void inbox_received_handler(DictionaryIterator *iter, void *context) { } static void init() { - APP_LOG(APP_LOG_LEVEL_INFO, "You are running version 2.51 of the Breathe app."); + APP_LOG(APP_LOG_LEVEL_INFO, "You are running version 2.52 of the Breathe app."); // Open AppMessage connection app_message_register_inbox_received(inbox_received_handler); app_message_open(256, 256); @@ -70,7 +70,7 @@ static void init() { wakeup_schedule_next_wakeup(settings_get_reminderHours(), 0, settings_get_reminderHoursStart()); } } else { - APP_LOG(APP_LOG_LEVEL_DEBUG, "Heap free is %d.", (int)heap_bytes_free()); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "Heap free is %d.", (int)heap_bytes_free()); // reminder_window_push(); // For testing // The app was started by the user; push the standard breathe window if (settings_get_rememberDuration() && data_read_last_duration_data() != 0) { // Set the minutes to breathe to the same as last one, unless the number is zero (meaning they haven't breathed yet) @@ -83,7 +83,7 @@ static void init() { if (persist_exists(SNOOZE_WAKEUP)) { if (wakeup_query(persist_read_int(SNOOZE_WAKEUP), NULL)) { // Returns true if the wakeup at this ID is still scheduled // Canceled a snooze timer! - APP_LOG(APP_LOG_LEVEL_DEBUG, "Cancelling a timer at %d.", (int)persist_read_int(SNOOZE_WAKEUP)); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "Cancelling a timer at %d.", (int)persist_read_int(SNOOZE_WAKEUP)); wakeup_cancel(persist_read_int(SNOOZE_WAKEUP)); } } @@ -103,7 +103,7 @@ static void init() { // data_set_streak_date_persist_data(); new_version_window_push(false); } else { - APP_LOG(APP_LOG_LEVEL_DEBUG, "The user has already seen the new version page!"); +// APP_LOG(APP_LOG_LEVEL_DEBUG, "The user has already seen the new version page!"); } #endif // achievement_menu_window_push(); // For testing diff --git a/src/c/settings_menu.c b/src/c/settings_menu.c index 0e85964..e14b6cc 100644 --- a/src/c/settings_menu.c +++ b/src/c/settings_menu.c @@ -206,7 +206,7 @@ static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuI case 5: // This is the about section switch (cell_index->row) { case 0: // This is the version number - menu_cell_basic_draw(ctx, cell_layer, localize_get_version_row_title(), "v2.51, 2017-11-13", NULL); + menu_cell_basic_draw(ctx, cell_layer, localize_get_version_row_title(), "v2.52, 2017-12-16", NULL); break; case 1: // This is the credits menu_cell_basic_draw(ctx, cell_layer, localize_get_credits_row_title(), "cheeseisdisgusting", NULL); diff --git a/src/pkjs/config-de.js b/src/pkjs/config-de.js index 28878f4..a9708a4 100644 --- a/src/pkjs/config-de.js +++ b/src/pkjs/config-de.js @@ -5,7 +5,7 @@ module.exports = [ }, { "type": "text", - "defaultValue": "Dies sind die Einstellungen für die Breathe-App. Sie benutzen Version 2.51 von Breathe.", + "defaultValue": "Dies sind die Einstellungen für die Breathe-App. Sie benutzen Version 2.52 von Breathe.", }, { "type": "section", diff --git a/src/pkjs/config-es.js b/src/pkjs/config-es.js index 71b1709..f19d64a 100644 --- a/src/pkjs/config-es.js +++ b/src/pkjs/config-es.js @@ -5,7 +5,7 @@ module.exports = [ }, { "type": "text", - "defaultValue": "Esta es la página de ajustes para la app Breathe. Estás usando la versión 2.51 de la app.", + "defaultValue": "Esta es la página de ajustes para la app Breathe. Estás usando la versión 2.52 de la app.", }, { "type": "section", diff --git a/src/pkjs/config-fr.js b/src/pkjs/config-fr.js index 28cc085..ee7009b 100644 --- a/src/pkjs/config-fr.js +++ b/src/pkjs/config-fr.js @@ -5,7 +5,7 @@ module.exports = [ }, { "type": "text", - "defaultValue": "Ceci est la page de configuration pour l'app Breathe. Vous utilisez version 2.51 de l'app.", + "defaultValue": "Ceci est la page de configuration pour l'app Breathe. Vous utilisez version 2.52 de l'app.", }, { "type": "section", diff --git a/src/pkjs/config.js b/src/pkjs/config.js index 6952ed7..1c1b8c7 100644 --- a/src/pkjs/config.js +++ b/src/pkjs/config.js @@ -5,7 +5,7 @@ module.exports = [ }, { "type": "text", - "defaultValue": "This is the settings page for the Breathe app. You are running version 2.51 of Breathe.", + "defaultValue": "This is the settings page for the Breathe app. You are running version 2.52 of Breathe.", }, { "type": "section",