From a33a4610742ebf68d0d231f9bb12b488933cc47a Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 14 Jul 2023 02:43:32 +0200 Subject: [PATCH] Update apps --- applications/external/4inrow/4inrow.c | 1 + applications/external/blackjack/blackjack.c | 3 +- .../external/brainfuck/application.fam | 2 +- applications/external/brainfuck/brainfuck_i.h | 1 - .../external/brainfuck/views/bf_dev_env.c | 12 +- .../external/caesarcipher/application.fam | 2 +- .../external/calculator/application.fam | 2 +- .../external/cntdown_timer/application.fam | 4 +- .../cntdown_timer/views/countdown_view.c | 3 + applications/external/counter/application.fam | 4 +- .../external/esp8266_deauth/application.fam | 2 +- applications/external/flipbip/application.fam | 2 +- applications/external/flipbip/flipbip.h | 2 +- .../external/flipbip/helpers/flipbip_file.c | 1 - .../external/flipbip/lib/crypto/rand.c | 74 ++++----- .../flipbip/scenes/flipbip_scene_scene_1.c | 2 +- .../external/flipbip/views/flipbip_scene_1.c | 114 ++++++++----- .../flizzer_tracker/flizzer_tracker.c | 7 +- .../flizzer_tracker/flizzer_tracker.h | 7 +- .../flizzer_tracker/flizzer_tracker_hal.c | 2 +- .../external/flizzer_tracker/init_deinit.c | 1 + .../sound_engine/sound_engine.c | 4 +- .../sound_engine/sound_engine_adsr.c | 3 +- applications/external/geiger/application.fam | 2 +- applications/external/geiger/flipper_geiger.c | 58 +++++++ applications/external/ifttt/application.fam | 2 +- .../external/ifttt/ifttt_virtual_button.c | 10 +- applications/external/ifttt/views/send_view.c | 2 +- .../external/ir_remote/application.fam | 2 +- .../external/mifare_fuzzer/mifare_fuzzer.c | 1 + applications/external/nightstand/clock_app.c | 2 +- applications/external/nrf24batch/nrf24batch.c | 23 ++- applications/external/passgen/application.fam | 2 +- applications/external/passgen/passgen.c | 22 +-- .../external/pomodoro/application.fam | 4 +- .../external/pomodoro/flipp_pomodoro_app.c | 27 +++- .../external/pomodoro/flipp_pomodoro_app.h | 6 + .../external/pomodoro/flipp_pomodoro_app_i.h | 3 +- .../images/flipp_pomodoro_learn_50x128.png | Bin 0 -> 1234 bytes .../pomodoro/modules/flipp_pomodoro.h | 1 - .../modules/flipp_pomodoro_statistics.c | 26 +++ .../modules/flipp_pomodoro_statistics.h | 45 ++++++ .../config/flipp_pomodoro_scene_config.h | 1 + .../pomodoro/scenes/flipp_pomodoro_scene.h | 1 + .../scenes/flipp_pomodoro_scene_info.c | 59 +++++++ .../scenes/flipp_pomodoro_scene_timer.c | 12 +- .../pomodoro/views/flipp_pomodoro_info_view.c | 152 ++++++++++++++++++ .../pomodoro/views/flipp_pomodoro_info_view.h | 71 ++++++++ .../views/flipp_pomodoro_timer_view.c | 5 +- applications/external/pong/application.fam | 2 +- applications/external/pong/pong.png | Bin 6459 -> 7315 bytes applications/external/qrcode/application.fam | 2 +- .../rubiks_cube_scrambler/application.fam | 2 +- .../external/scorched_tanks/application.fam | 4 +- .../scorched_tanks/scorchedTanks_10px.png | Bin 614 -> 536 bytes applications/external/snake_2/snake_20.c | 3 +- applications/external/solitaire/solitaire.c | 3 +- applications/external/text2sam/stm32_sam.cpp | 9 +- .../external/timelapse/application.fam | 2 +- applications/external/timelapse/zeitraffer.c | 9 +- .../external/tuning_fork/tuning_fork.c | 1 - applications/external/unitemp/application.fam | 1 + applications/external/videopoker/poker.c | 1 - .../wifi_marauder_companion/application.fam | 30 ++-- .../external/wifi_scanner/application.fam | 2 +- 65 files changed, 696 insertions(+), 169 deletions(-) create mode 100644 applications/external/pomodoro/images/flipp_pomodoro_learn_50x128.png create mode 100644 applications/external/pomodoro/modules/flipp_pomodoro_statistics.c create mode 100644 applications/external/pomodoro/modules/flipp_pomodoro_statistics.h create mode 100644 applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c create mode 100644 applications/external/pomodoro/views/flipp_pomodoro_info_view.c create mode 100644 applications/external/pomodoro/views/flipp_pomodoro_info_view.h diff --git a/applications/external/4inrow/4inrow.c b/applications/external/4inrow/4inrow.c index e9b7b6c69..1f112a81a 100644 --- a/applications/external/4inrow/4inrow.c +++ b/applications/external/4inrow/4inrow.c @@ -4,6 +4,7 @@ #include #include #include +#include static int matrix[6][7] = {0}; static int cursorx = 3; diff --git a/applications/external/blackjack/blackjack.c b/applications/external/blackjack/blackjack.c index 91a493228..50d8e30f6 100644 --- a/applications/external/blackjack/blackjack.c +++ b/applications/external/blackjack/blackjack.c @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -629,4 +630,4 @@ free_and_exit: furi_message_queue_free(event_queue); return return_code; -} +} \ No newline at end of file diff --git a/applications/external/brainfuck/application.fam b/applications/external/brainfuck/application.fam index 9ee518fbe..e7da3af73 100644 --- a/applications/external/brainfuck/application.fam +++ b/applications/external/brainfuck/application.fam @@ -9,7 +9,7 @@ App( ], stack_size=8 * 1024, fap_icon="bfico.png", - fap_category="Misc", + fap_category="Tools", fap_icon_assets="icons", fap_author="@nymda", fap_weburl="https://github.com/nymda/FlipperZeroBrainfuck", diff --git a/applications/external/brainfuck/brainfuck_i.h b/applications/external/brainfuck/brainfuck_i.h index 293654c3e..1258c5d3c 100644 --- a/applications/external/brainfuck/brainfuck_i.h +++ b/applications/external/brainfuck/brainfuck_i.h @@ -38,7 +38,6 @@ typedef unsigned char byte; #include #include -#include #define BF_INST_BUFFER_SIZE 2048 #define BF_OUTPUT_SIZE 512 diff --git a/applications/external/brainfuck/views/bf_dev_env.c b/applications/external/brainfuck/views/bf_dev_env.c index 241a4ebc3..4167414c3 100644 --- a/applications/external/brainfuck/views/bf_dev_env.c +++ b/applications/external/brainfuck/views/bf_dev_env.c @@ -20,6 +20,12 @@ typedef struct { int right; } bMapping; +#ifdef FW_ORIGIN_Official +#define FONT_NAME FontSecondary +#else +#define FONT_NAME FontBatteryPercent +#endif + static bool bf_dev_process_up(BFDevEnv* devEnv); static bool bf_dev_process_down(BFDevEnv* devEnv); static bool bf_dev_process_left(BFDevEnv* devEnv); @@ -63,7 +69,7 @@ static void bf_dev_draw_button(Canvas* canvas, int x, int y, bool selected, cons if(selected) { canvas_draw_rbox(canvas, x, y, BT_X, BT_Y, 3); canvas_invert_color(canvas); - canvas_set_font(canvas, FontBatteryPercent); + canvas_set_font(canvas, FONT_NAME); canvas_draw_str_aligned( canvas, x + (BT_X / 2), y + (BT_Y / 2) - 1, AlignCenter, AlignCenter, lbl); canvas_invert_color(canvas); @@ -73,7 +79,7 @@ static void bf_dev_draw_button(Canvas* canvas, int x, int y, bool selected, cons canvas_draw_rbox(canvas, x + 2, y - 1, BT_X - 2, BT_Y - 1, 3); canvas_invert_color(canvas); canvas_draw_rframe(canvas, x, y, BT_X, BT_Y, 3); - canvas_set_font(canvas, FontBatteryPercent); + canvas_set_font(canvas, FONT_NAME); canvas_draw_str_aligned( canvas, x + (BT_X / 2), y + (BT_Y / 2) - 1, AlignCenter, AlignCenter, lbl); } @@ -131,7 +137,7 @@ static void bf_dev_draw_callback(Canvas* canvas, void* _model) { //textbox //grossly overcomplicated. not fixing it. canvas_draw_rframe(canvas, 1, 1, 126, 33, 2); - canvas_set_font(canvas, FontBatteryPercent); + canvas_set_font(canvas, FONT_NAME); int dbOffset = 0; if(appDev->dataSize > 72) { diff --git a/applications/external/caesarcipher/application.fam b/applications/external/caesarcipher/application.fam index 7f973d54a..fdb1052b0 100644 --- a/applications/external/caesarcipher/application.fam +++ b/applications/external/caesarcipher/application.fam @@ -9,7 +9,7 @@ App( ], stack_size=2 * 1024, fap_icon="caesar_cipher_icon.png", - fap_category="Misc", + fap_category="Tools", order=20, fap_author="@panki27", fap_weburl="https://github.com/panki27/caesar-cipher", diff --git a/applications/external/calculator/application.fam b/applications/external/calculator/application.fam index 1913e5503..cba45e49b 100644 --- a/applications/external/calculator/application.fam +++ b/applications/external/calculator/application.fam @@ -8,7 +8,7 @@ App( stack_size=1 * 1024, order=45, fap_icon="calcIcon.png", - fap_category="Misc", + fap_category="Tools", fap_author="@n-o-T-I-n-s-a-n-e", fap_weburl="https://github.com/n-o-T-I-n-s-a-n-e", fap_version="1.0", diff --git a/applications/external/cntdown_timer/application.fam b/applications/external/cntdown_timer/application.fam index 10d610d0f..054833eeb 100644 --- a/applications/external/cntdown_timer/application.fam +++ b/applications/external/cntdown_timer/application.fam @@ -12,9 +12,9 @@ App( stack_size=2 * 1024, order=20, fap_icon="cntdown_timer.png", - fap_category="Misc", + fap_category="Tools", fap_author="@0w0mewo", fap_weburl="https://github.com/0w0mewo/fpz_cntdown_timer", - fap_version="1.0", + fap_version="1.1", fap_description="Simple count down timer", ) diff --git a/applications/external/cntdown_timer/views/countdown_view.c b/applications/external/cntdown_timer/views/countdown_view.c index 97e8cb248..94e53ac55 100644 --- a/applications/external/cntdown_timer/views/countdown_view.c +++ b/applications/external/cntdown_timer/views/countdown_view.c @@ -129,6 +129,9 @@ static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) { handle_misc_cmd(hw, CountDownTimerToggleCounting); } break; + case InputKeyBack: + return false; + break; default: break; diff --git a/applications/external/counter/application.fam b/applications/external/counter/application.fam index 3678c644d..6f2703307 100644 --- a/applications/external/counter/application.fam +++ b/applications/external/counter/application.fam @@ -6,10 +6,10 @@ App( requires=[ "gui", ], - fap_category="Misc", + fap_category="Tools", fap_icon="counter_icon.png", fap_author="@Krulknul", fap_weburl="https://github.com/Krulknul/dolphin-counter", - fap_version="1.0", + fap_version="1.1", fap_description="Simple counter", ) diff --git a/applications/external/esp8266_deauth/application.fam b/applications/external/esp8266_deauth/application.fam index 23ae94dce..9b176a3dd 100644 --- a/applications/external/esp8266_deauth/application.fam +++ b/applications/external/esp8266_deauth/application.fam @@ -5,7 +5,7 @@ App( entry_point="esp8266_deauth_app", requires=["gui"], stack_size=2 * 1024, - order=20, + order=100, fap_icon="wifi_10px.png", fap_category="WiFi", fap_author="@SequoiaSan & @xMasterX", diff --git a/applications/external/flipbip/application.fam b/applications/external/flipbip/application.fam index e8c660a89..0c17d5787 100644 --- a/applications/external/flipbip/application.fam +++ b/applications/external/flipbip/application.fam @@ -15,7 +15,7 @@ App( name="crypto", ), ], - fap_category="Misc", + fap_category="Tools", fap_description="Crypto toolkit for Flipper", fap_author="Struan Clark (xtruan)", fap_weburl="https://github.com/xtruan/FlipBIP", diff --git a/applications/external/flipbip/flipbip.h b/applications/external/flipbip/flipbip.h index 6f84a1736..527807011 100644 --- a/applications/external/flipbip/flipbip.h +++ b/applications/external/flipbip/flipbip.h @@ -15,7 +15,7 @@ #include "views/flipbip_startscreen.h" #include "views/flipbip_scene_1.h" -#define FLIPBIP_VERSION "v0.0.9" +#define FLIPBIP_VERSION "v1.0.0" #define COIN_BTC 0 #define COIN_DOGE 3 diff --git a/applications/external/flipbip/helpers/flipbip_file.c b/applications/external/flipbip/helpers/flipbip_file.c index 3b61b6b95..fd389e48e 100644 --- a/applications/external/flipbip/helpers/flipbip_file.c +++ b/applications/external/flipbip/helpers/flipbip_file.c @@ -1,6 +1,5 @@ #include "flipbip_file.h" #include -#include #include #include "../helpers/flipbip_string.h" // From: lib/crypto diff --git a/applications/external/flipbip/lib/crypto/rand.c b/applications/external/flipbip/lib/crypto/rand.c index b35214285..67a97876d 100644 --- a/applications/external/flipbip/lib/crypto/rand.c +++ b/applications/external/flipbip/lib/crypto/rand.c @@ -21,43 +21,25 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -// NOTE: -// random32() and random_buffer() have been replaced in this implementation -// with Flipper Zero specific code. The original code is commented out below. +#define FLIPPER_HAL_RANDOM #include "rand.h" +#ifdef FLIPPER_HAL_RANDOM + +// NOTE: +// random32() and random_buffer() have been replaced in this implementation +// with Flipper Zero specific code. The original code is disabled by #define. + // Flipper Zero RNG code: #include -#ifndef RAND_PLATFORM_INDEPENDENT - -// Original code: -// #pragma message("NOT SUITABLE FOR PRODUCTION USE! Replace random32() function with your own secure code.") - -// The following code is not supposed to be used in a production environment. -// It's included only to make the library testable. -// The message above tries to prevent any accidental use outside of the test -// environment. -// -// You are supposed to replace the random8() and random32() function with your -// own secure code. There is also a possibility to replace the random_buffer() -// function as it is defined as a weak symbol. - static uint32_t seed = 0; void random_reseed(const uint32_t value) { seed = value; } -// Original code: -// uint32_t random32(void) { -// // Linear congruential generator from Numerical Recipes -// // https://en.wikipedia.org/wiki/Linear_congruential_generator -// seed = 1664525 * seed + 1013904223; -// return seed; -// } - // Flipper Zero RNG code: uint32_t random32(void) { return furi_hal_random_get(); @@ -68,22 +50,42 @@ void random_buffer(uint8_t* buf, size_t len) { furi_hal_random_fill_buf(buf, len); } -#endif /* RAND_PLATFORM_INDEPENDENT */ +#else /* PLATFORM INDEPENDENT */ + +#pragma message( \ + "NOT SUITABLE FOR PRODUCTION USE! Replace random32() function with your own secure code.") + +// The following code is not supposed to be used in a production environment. +// It's included only to make the library testable. +// The message above tries to prevent any accidental use outside of the test +// environment. +// +// You are supposed to replace the random8() and random32() function with your +// own secure code. There is also a possibility to replace the random_buffer() +// function as it is defined as a weak symbol. // // The following code is platform independent // -// Original code: -// void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len) { -// uint32_t r = 0; -// for (size_t i = 0; i < len; i++) { -// if (i % 4 == 0) { -// r = random32(); -// } -// buf[i] = (r >> ((i % 4) * 8)) & 0xFF; -// } -// } +uint32_t random32(void) { + // Linear congruential generator from Numerical Recipes + // https://en.wikipedia.org/wiki/Linear_congruential_generator + seed = 1664525 * seed + 1013904223; + return seed; +} + +void __attribute__((weak)) random_buffer(uint8_t* buf, size_t len) { + uint32_t r = 0; + for(size_t i = 0; i < len; i++) { + if(i % 4 == 0) { + r = random32(); + } + buf[i] = (r >> ((i % 4) * 8)) & 0xFF; + } +} + +#endif /* FLIPPER_HAL_RANDOM */ uint32_t random_uniform(uint32_t n) { uint32_t x = 0, max = 0xFFFFFFFF - (0xFFFFFFFF % n); diff --git a/applications/external/flipbip/scenes/flipbip_scene_scene_1.c b/applications/external/flipbip/scenes/flipbip_scene_scene_1.c index 6f4064cd4..2f0201443 100644 --- a/applications/external/flipbip/scenes/flipbip_scene_scene_1.c +++ b/applications/external/flipbip/scenes/flipbip_scene_scene_1.c @@ -47,4 +47,4 @@ bool flipbip_scene_scene_1_on_event(void* context, SceneManagerEvent event) { void flipbip_scene_scene_1_on_exit(void* context) { FlipBip* app = context; UNUSED(app); -} \ No newline at end of file +} diff --git a/applications/external/flipbip/views/flipbip_scene_1.c b/applications/external/flipbip/views/flipbip_scene_1.c index 3437a1149..f57fe4830 100644 --- a/applications/external/flipbip/views/flipbip_scene_1.c +++ b/applications/external/flipbip/views/flipbip_scene_1.c @@ -23,7 +23,9 @@ #define DERIV_ACCOUNT 0 #define DERIV_CHANGE 0 -#define MAX_ADDR_LEN 42 + 1 // 42 = max length of address + null terminator +#define MAX_TEXT_LEN 30 // 30 = max length of text +#define MAX_TEXT_BUF (MAX_TEXT_LEN + 1) // max length of text + null terminator +#define MAX_ADDR_BUF (42 + 1) // 42 = max length of address + null terminator #define NUM_ADDRS 6 #define PAGE_LOADING 0 @@ -44,10 +46,10 @@ #define TEXT_RECEIVE_ADDRESS "receive address:" #define TEXT_DEFAULT_DERIV "m/44'/X'/0'/0" const char* TEXT_INFO = "-Scroll pages with up/down-" - "p1,2) Mnemonic/Seed " - "p3) xprv Root Key " - "p4,5) xprv/xpub Accnt Keys" - "p6,7) xprv/xpub Extnd Keys" + "p1,2) BIP39 Mnemonic/Seed" + "p3) BIP32 Root Key " + "p4,5) Prv/Pub Account Keys" + "p6,7) Prv/Pub BIP32 Keys " "p8+) Receive Addresses "; // #define TEXT_SAVE_QR "Save QR" @@ -98,6 +100,10 @@ static CONFIDENTIAL char* s_disp_text5 = NULL; static CONFIDENTIAL char* s_disp_text6 = NULL; // Derivation path text static const char* s_derivation_text = TEXT_DEFAULT_DERIV; +// Warning text +static bool s_warn_insecure = false; +#define WARN_INSECURE_TEXT_1 "Recommendation:" +#define WARN_INSECURE_TEXT_2 "Set BIP39 Passphrase" //static bool s_busy = false; void flipbip_scene_1_set_callback( @@ -117,13 +123,15 @@ static void flipbip_scene_1_init_address( uint32_t addr_index) { //s_busy = true; - // Buffer for address serialization - const size_t buflen = 40; - char buf[40 + 1] = {0}; + // buffer for address serialization + // subtract 2 for "0x", 1 for null terminator + const size_t buflen = MAX_ADDR_BUF - (2 + 1); + // subtract 2 for "0x" + char buf[MAX_ADDR_BUF - 2] = {0}; // Use static node for address generation memcpy(s_addr_node, node, sizeof(HDNode)); - memzero(addr_text, MAX_ADDR_LEN); + memzero(addr_text, MAX_ADDR_BUF); hdnode_private_ckd(s_addr_node, addr_index); hdnode_fill_public_key(s_addr_node); @@ -158,8 +166,13 @@ static void flipbip_scene_1_init_address( //s_busy = false; } -static void flipbip_scene_1_draw_generic(const char* text, size_t line_len) { +static void + flipbip_scene_1_draw_generic(const char* text, const size_t line_len, const bool chunk) { // Split the text into parts + size_t len = line_len; + if(len > MAX_TEXT_LEN) { + len = MAX_TEXT_LEN; + } for(size_t si = 1; si <= 6; si++) { char* ptr = NULL; @@ -176,11 +189,18 @@ static void flipbip_scene_1_draw_generic(const char* text, size_t line_len) { else if(si == 6) ptr = s_disp_text6; - memzero(ptr, 30 + 1); - if(line_len > 30) { - strncpy(ptr, text + ((si - 1) * 30), 30); - } else { - strncpy(ptr, text + ((si - 1) * line_len), line_len); + memzero(ptr, MAX_TEXT_BUF); + strncpy(ptr, text + ((si - 1) * len), len); + // add a space every 4 characters and shift the text + if(len < 23 && chunk) { + for(size_t i = 0; i < strlen(ptr); i++) { + if(i % 5 == 0) { + for(size_t j = strlen(ptr); j > i; j--) { + ptr[j] = ptr[j - 1]; + } + ptr[i] = ' '; + } + } } } } @@ -220,9 +240,9 @@ static void flipbip_scene_1_draw_mnemonic(const char* mnemonic) { else if(mi == 6) ptr = s_disp_text6; - memzero(ptr, 30 + 1); - if(strlen(mnemonic_part) > 30) { - strncpy(ptr, mnemonic_part, 30); + memzero(ptr, MAX_TEXT_BUF); + if(strlen(mnemonic_part) > MAX_TEXT_LEN) { + strncpy(ptr, mnemonic_part, MAX_TEXT_LEN); } else { strncpy(ptr, mnemonic_part, strlen(mnemonic_part)); } @@ -241,7 +261,7 @@ static void flipbip_scene_1_draw_seed(FlipBipScene1Model* const model) { // Convert the seed to a hex string flipbip_btox(model->seed, 64, seed_working); - flipbip_scene_1_draw_generic(seed_working, 22); + flipbip_scene_1_draw_generic(seed_working, 22, false); // Free the working seed memory memzero(seed_working, seed_working_len); @@ -249,12 +269,12 @@ static void flipbip_scene_1_draw_seed(FlipBipScene1Model* const model) { } static void flipbip_scene_1_clear_text() { - memzero((void*)s_disp_text1, 30 + 1); - memzero((void*)s_disp_text2, 30 + 1); - memzero((void*)s_disp_text3, 30 + 1); - memzero((void*)s_disp_text4, 30 + 1); - memzero((void*)s_disp_text5, 30 + 1); - memzero((void*)s_disp_text6, 30 + 1); + memzero((void*)s_disp_text1, MAX_TEXT_BUF); + memzero((void*)s_disp_text2, MAX_TEXT_BUF); + memzero((void*)s_disp_text3, MAX_TEXT_BUF); + memzero((void*)s_disp_text4, MAX_TEXT_BUF); + memzero((void*)s_disp_text5, MAX_TEXT_BUF); + memzero((void*)s_disp_text6, MAX_TEXT_BUF); } void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { @@ -264,35 +284,40 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) { flipbip_scene_1_clear_text(); if(model->page == PAGE_INFO) { - flipbip_scene_1_draw_generic(TEXT_INFO, 27); + flipbip_scene_1_draw_generic(TEXT_INFO, 27, false); } else if(model->page == PAGE_MNEMONIC) { flipbip_scene_1_draw_mnemonic(model->mnemonic); } else if(model->page == PAGE_SEED) { flipbip_scene_1_draw_seed(model); } else if(model->page == PAGE_XPRV_ROOT) { - flipbip_scene_1_draw_generic(model->xprv_root, 20); + flipbip_scene_1_draw_generic(model->xprv_root, 20, false); } else if(model->page == PAGE_XPRV_ACCT) { - flipbip_scene_1_draw_generic(model->xprv_account, 20); + flipbip_scene_1_draw_generic(model->xprv_account, 20, false); } else if(model->page == PAGE_XPUB_ACCT) { - flipbip_scene_1_draw_generic(model->xpub_account, 20); + flipbip_scene_1_draw_generic(model->xpub_account, 20, false); } else if(model->page == PAGE_XPRV_EXTD) { - flipbip_scene_1_draw_generic(model->xprv_extended, 20); + flipbip_scene_1_draw_generic(model->xprv_extended, 20, false); } else if(model->page == PAGE_XPUB_EXTD) { - flipbip_scene_1_draw_generic(model->xpub_extended, 20); + flipbip_scene_1_draw_generic(model->xpub_extended, 20, false); } else if(model->page >= PAGE_ADDR_BEGIN && model->page <= PAGE_ADDR_END) { - uint32_t line_len = 12; + size_t line_len = 12; if(model->coin == FlipBipCoinETH60) { line_len = 14; } flipbip_scene_1_draw_generic( - model->recv_addresses[model->page - PAGE_ADDR_BEGIN], line_len); + model->recv_addresses[model->page - PAGE_ADDR_BEGIN], line_len, true); } if(model->page == PAGE_LOADING) { canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 2, 10, TEXT_LOADING); canvas_draw_str(canvas, 7, 30, s_derivation_text); - canvas_draw_icon(canvas, 86, 25, &I_Keychain_39x36); + canvas_draw_icon(canvas, 86, 22, &I_Keychain_39x36); + if(s_warn_insecure) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 50, WARN_INSECURE_TEXT_1); + canvas_draw_str(canvas, 2, 60, WARN_INSECURE_TEXT_2); + } } else if(model->page >= PAGE_ADDR_BEGIN && model->page <= PAGE_ADDR_END) { // draw address header canvas_set_font(canvas, FontSecondary); @@ -461,8 +486,8 @@ static int flipbip_scene_1_model_init( // Initialize addresses for(uint8_t a = 0; a < NUM_ADDRS; a++) { - model->recv_addresses[a] = malloc(MAX_ADDR_LEN); - memzero(model->recv_addresses[a], MAX_ADDR_LEN); + model->recv_addresses[a] = malloc(MAX_ADDR_BUF); + memzero(model->recv_addresses[a], MAX_ADDR_BUF); flipbip_scene_1_init_address(model->recv_addresses[a], node, coin, a); // Save QR code file @@ -586,7 +611,7 @@ void flipbip_scene_1_exit(void* context) { free((void*)model->xprv_extended); free((void*)model->xpub_extended); for(int a = 0; a < NUM_ADDRS; a++) { - memzero((void*)model->recv_addresses[a], MAX_ADDR_LEN); + memzero((void*)model->recv_addresses[a], MAX_ADDR_BUF); free((void*)model->recv_addresses[a]); } } @@ -614,6 +639,9 @@ void flipbip_scene_1_enter(void* context) { const char* passphrase_text = ""; if(app->passphrase == FlipBipPassphraseOn && strlen(app->passphrase_text) > 0) { passphrase_text = app->passphrase_text; + s_warn_insecure = false; + } else { + s_warn_insecure = true; } // BIP44 Coin setting @@ -685,12 +713,12 @@ FlipBipScene1* flipbip_scene_1_alloc() { s_addr_node = (HDNode*)malloc(sizeof(HDNode)); // allocate the display text - s_disp_text1 = (char*)malloc(30 + 1); - s_disp_text2 = (char*)malloc(30 + 1); - s_disp_text3 = (char*)malloc(30 + 1); - s_disp_text4 = (char*)malloc(30 + 1); - s_disp_text5 = (char*)malloc(30 + 1); - s_disp_text6 = (char*)malloc(30 + 1); + s_disp_text1 = (char*)malloc(MAX_TEXT_BUF); + s_disp_text2 = (char*)malloc(MAX_TEXT_BUF); + s_disp_text3 = (char*)malloc(MAX_TEXT_BUF); + s_disp_text4 = (char*)malloc(MAX_TEXT_BUF); + s_disp_text5 = (char*)malloc(MAX_TEXT_BUF); + s_disp_text6 = (char*)malloc(MAX_TEXT_BUF); return instance; } diff --git a/applications/external/flizzer_tracker/flizzer_tracker.c b/applications/external/flizzer_tracker/flizzer_tracker.c index ed696cdc6..2c0729a43 100644 --- a/applications/external/flizzer_tracker/flizzer_tracker.c +++ b/applications/external/flizzer_tracker/flizzer_tracker.c @@ -99,7 +99,10 @@ int32_t flizzer_tracker_app(void* p) { UNUSED(p); Storage* storage = furi_record_open(RECORD_STORAGE); - storage_simply_mkdir(storage, FLIZZER_TRACKER_INSTRUMENTS_FOLDER); + bool st = storage_simply_mkdir(storage, APPSDATA_FOLDER); + st = storage_simply_mkdir(storage, FLIZZER_TRACKER_FOLDER); + st = storage_simply_mkdir(storage, FLIZZER_TRACKER_INSTRUMENTS_FOLDER); + UNUSED(st); furi_record_close(RECORD_STORAGE); FlizzerTrackerApp* tracker = init_tracker(44100, 50, true, 1024); @@ -212,4 +215,4 @@ int32_t flizzer_tracker_app(void* p) { deinit_tracker(tracker); return 0; -} +} \ No newline at end of file diff --git a/applications/external/flizzer_tracker/flizzer_tracker.h b/applications/external/flizzer_tracker/flizzer_tracker.h index 6ece14e20..97269a98e 100644 --- a/applications/external/flizzer_tracker/flizzer_tracker.h +++ b/applications/external/flizzer_tracker/flizzer_tracker.h @@ -22,8 +22,9 @@ #include "sound_engine/sound_engine_filter.h" #include "tracker_engine/tracker_engine_defs.h" -#define FLIZZER_TRACKER_FOLDER STORAGE_APP_DATA_PATH_PREFIX -#define FLIZZER_TRACKER_INSTRUMENTS_FOLDER APP_DATA_PATH("instruments") +#define APPSDATA_FOLDER "/ext/apps_data" +#define FLIZZER_TRACKER_FOLDER "/ext/apps_data/flizzer_tracker" +#define FLIZZER_TRACKER_INSTRUMENTS_FOLDER "/ext/apps_data/flizzer_tracker/instruments" #define FILE_NAME_LEN 64 typedef enum { @@ -222,4 +223,4 @@ typedef struct { } TrackerViewModel; void draw_callback(Canvas* canvas, void* ctx); -bool input_callback(InputEvent* input_event, void* ctx); +bool input_callback(InputEvent* input_event, void* ctx); \ No newline at end of file diff --git a/applications/external/flizzer_tracker/flizzer_tracker_hal.c b/applications/external/flizzer_tracker/flizzer_tracker_hal.c index a2f483f08..d229598bf 100644 --- a/applications/external/flizzer_tracker/flizzer_tracker_hal.c +++ b/applications/external/flizzer_tracker/flizzer_tracker_hal.c @@ -310,4 +310,4 @@ void play() { void stop() { sound_engine_stop(); tracker_engine_stop(); -} +} \ No newline at end of file diff --git a/applications/external/flizzer_tracker/init_deinit.c b/applications/external/flizzer_tracker/init_deinit.c index 33e42fe36..0887f5506 100644 --- a/applications/external/flizzer_tracker/init_deinit.c +++ b/applications/external/flizzer_tracker/init_deinit.c @@ -262,6 +262,7 @@ void deinit_tracker(FlizzerTrackerApp* tracker) { view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SETTINGS); view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE); view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT); + view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_INSTRUMENT_FILE_OVERWRITE); view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN_COPYPASTE); view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN); view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_KEYBOARD); diff --git a/applications/external/flizzer_tracker/sound_engine/sound_engine.c b/applications/external/flizzer_tracker/sound_engine/sound_engine.c index 4908c9226..05ccaf2bb 100644 --- a/applications/external/flizzer_tracker/sound_engine/sound_engine.c +++ b/applications/external/flizzer_tracker/sound_engine/sound_engine.c @@ -34,6 +34,8 @@ void sound_engine_init( sound_engine->sine_lut[i] = (uint8_t)((sinf(i / 64.0 * PI) + 1.0) * 127.0); } + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); + furi_hal_interrupt_set_isr_ex( FuriHalInterruptIdDma1Ch1, 15, sound_engine_dma_isr, sound_engine); @@ -54,7 +56,7 @@ void sound_engine_deinit(SoundEngine* sound_engine) { furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } - furi_hal_interrupt_set_isr_ex(FuriHalInterruptIdDma1Ch1, 13, NULL, NULL); + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); sound_engine_stop(); sound_engine_deinit_timer(); } diff --git a/applications/external/flizzer_tracker/sound_engine/sound_engine_adsr.c b/applications/external/flizzer_tracker/sound_engine/sound_engine_adsr.c index 21eb8f76b..07d405631 100644 --- a/applications/external/flizzer_tracker/sound_engine/sound_engine_adsr.c +++ b/applications/external/flizzer_tracker/sound_engine/sound_engine_adsr.c @@ -54,5 +54,6 @@ int32_t sound_engine_cycle_and_output_adsr( } } - return (int32_t)((int32_t)input * (int32_t)(adsr->envelope >> 10) / (int32_t)(MAX_ADSR >> 10) * (int32_t)adsr->volume / (int32_t)MAX_ADSR_VOLUME); + return (int32_t)((int32_t)input * (int32_t)(adsr->envelope >> 10) / (int32_t)(MAX_ADSR >> 10) * + (int32_t)adsr->volume / (int32_t)MAX_ADSR_VOLUME); } \ No newline at end of file diff --git a/applications/external/geiger/application.fam b/applications/external/geiger/application.fam index eca3167e4..4721ff778 100644 --- a/applications/external/geiger/application.fam +++ b/applications/external/geiger/application.fam @@ -7,7 +7,7 @@ App( requires=[ "gui", ], - stack_size=1 * 1024, + stack_size=2 * 1024, fap_icon="geiger.png", fap_category="GPIO", fap_author="@nmrr", diff --git a/applications/external/geiger/flipper_geiger.c b/applications/external/geiger/flipper_geiger.c index 17f2b7058..a9101a277 100644 --- a/applications/external/geiger/flipper_geiger.c +++ b/applications/external/geiger/flipper_geiger.c @@ -10,6 +10,10 @@ #include #include #include +#include +#include + +#include #define SCREEN_SIZE_X 128 #define SCREEN_SIZE_Y 64 @@ -147,6 +151,14 @@ int32_t flipper_geiger_app(void* p) { furi_delay_ms(10); } + Storage* storage = furi_record_open(RECORD_STORAGE); + Stream* file_stream = buffered_file_stream_alloc(storage); + FuriString* dataString = furi_string_alloc(); + uint32_t epoch = 0; + uint8_t recordData = 0; + + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + while(1) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); @@ -166,6 +178,36 @@ int32_t flipper_geiger_app(void* p) { screenRefresh = 1; furi_mutex_release(mutexVal.mutex); + } else if(event.input.key == InputKeyUp && event.input.type == InputTypeLong) { + if(recordData == 0) { + notification_message(notification, &sequence_set_only_red_255); + + FuriHalRtcDateTime datetime; + furi_hal_rtc_get_datetime(&datetime); + + char path[64]; + snprintf( + path, + sizeof(path), + EXT_PATH("/geiger-%.4d-%.2d-%.2d--%.2d-%.2d-%.2d.csv"), + datetime.year, + datetime.month, + datetime.day, + datetime.hour, + datetime.minute, + datetime.second); + + buffered_file_stream_open( + file_stream, path, FSAM_WRITE, FSOM_CREATE_ALWAYS); + furi_string_printf(dataString, "epoch,cps\n"); + stream_write_string(file_stream, dataString); + epoch = 0; + recordData = 1; + } else { + buffered_file_stream_close(file_stream); + notification_message(notification, &sequence_reset_red); + recordData = 0; + } } else if((event.input.key == InputKeyLeft && event.input.type == InputTypeShort)) { furi_mutex_acquire(mutexVal.mutex, FuriWaitForever); @@ -192,6 +234,11 @@ int32_t flipper_geiger_app(void* p) { } else if(event.type == ClockEventTypeTick) { furi_mutex_acquire(mutexVal.mutex, FuriWaitForever); + if(recordData == 1) { + furi_string_printf(dataString, "%lu,%lu\n", epoch++, counter); + stream_write_string(file_stream, dataString); + } + for(int i = 0; i < SCREEN_SIZE_X / 2 - 1; i++) mutexVal.line[SCREEN_SIZE_X / 2 - 1 - i] = mutexVal.line[SCREEN_SIZE_X / 2 - 2 - i]; @@ -222,6 +269,16 @@ int32_t flipper_geiger_app(void* p) { if(screenRefresh == 1) view_port_update(view_port); } + if(recordData == 1) { + buffered_file_stream_close(file_stream); + notification_message(notification, &sequence_reset_red); + } + + furi_string_free(dataString); + furi_record_close(RECORD_NOTIFICATION); + stream_free(file_stream); + furi_record_close(RECORD_STORAGE); + // Disable 5v power if(furi_hal_power_is_otg_enabled()) { furi_hal_power_disable_otg(); @@ -230,6 +287,7 @@ int32_t flipper_geiger_app(void* p) { furi_hal_gpio_disable_int_callback(&gpio_ext_pa7); furi_hal_gpio_remove_int_callback(&gpio_ext_pa7); furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_message_queue_free(event_queue); furi_mutex_free(mutexVal.mutex); diff --git a/applications/external/ifttt/application.fam b/applications/external/ifttt/application.fam index 195c8a9eb..1a86000a4 100644 --- a/applications/external/ifttt/application.fam +++ b/applications/external/ifttt/application.fam @@ -1,5 +1,5 @@ App( - appid="ifttt", + appid="esp8266_ifttt_virtual_button", name="[ESP8266] IFTTT Button", apptype=FlipperAppType.EXTERNAL, entry_point="ifttt_virtual_button_app", diff --git a/applications/external/ifttt/ifttt_virtual_button.c b/applications/external/ifttt/ifttt_virtual_button.c index 01a02b0f3..ba1684daf 100644 --- a/applications/external/ifttt/ifttt_virtual_button.c +++ b/applications/external/ifttt/ifttt_virtual_button.c @@ -1,7 +1,8 @@ #include "ifttt_virtual_button.h" -#define IFTTT_CONFIG_FOLDER APP_DATA_PATH("config") -const char* CONFIG_FILE_PATH = APP_DATA_PATH("config/config.settings"); +#define IFTTT_FOLDER "/ext/apps_data/ifttt" +#define IFTTT_CONFIG_FOLDER "/ext/apps_data/ifttt/config" +const char* CONFIG_FILE_PATH = "/ext/apps_data/ifttt/config/config.settings"; #define FLIPPERZERO_SERIAL_BAUD 115200 typedef enum ESerialCommand { ESerialCommand_Config } ESerialCommand; @@ -218,7 +219,10 @@ int32_t ifttt_virtual_button_app(void* p) { UNUSED(p); Storage* storage = furi_record_open(RECORD_STORAGE); - storage_simply_mkdir(storage, IFTTT_CONFIG_FOLDER); + if(!storage_simply_mkdir(storage, IFTTT_FOLDER)) { + } + if(!storage_simply_mkdir(storage, IFTTT_CONFIG_FOLDER)) { + } furi_record_close(RECORD_STORAGE); uint32_t first_scene = VirtualButtonAppSceneStart; diff --git a/applications/external/ifttt/views/send_view.c b/applications/external/ifttt/views/send_view.c index e1638e7a7..7debf650b 100644 --- a/applications/external/ifttt/views/send_view.c +++ b/applications/external/ifttt/views/send_view.c @@ -134,4 +134,4 @@ void send_view_set_data(SendView* send_view, bool connected) { furi_assert(send_view); with_view_model( send_view->view, SendViewModel * model, { model->connected = connected; }, true); -} \ No newline at end of file +} diff --git a/applications/external/ir_remote/application.fam b/applications/external/ir_remote/application.fam index 5a98bd904..d1ec0da80 100644 --- a/applications/external/ir_remote/application.fam +++ b/applications/external/ir_remote/application.fam @@ -8,7 +8,7 @@ App( "gui", "dialogs", ], - fap_category="Tools", + fap_category="Infrared", fap_icon="ir_10px.png", fap_author="@Hong5489 & @friebel & @d4ve10", fap_weburl="https://github.com/Hong5489/ir_remote", diff --git a/applications/external/mifare_fuzzer/mifare_fuzzer.c b/applications/external/mifare_fuzzer/mifare_fuzzer.c index 8f839cf35..76fec98ed 100644 --- a/applications/external/mifare_fuzzer/mifare_fuzzer.c +++ b/applications/external/mifare_fuzzer/mifare_fuzzer.c @@ -95,6 +95,7 @@ void mifare_fuzzer_free(MifareFuzzerApp* app) { //FURI_LOG_D(TAG, "mifare_fuzzer_free() :: Views"); view_dispatcher_remove_view(app->view_dispatcher, MifareFuzzerViewSelectCard); view_dispatcher_remove_view(app->view_dispatcher, MifareFuzzerViewSelectAttack); + view_dispatcher_remove_view(app->view_dispatcher, MifareFuzzerViewEmulator); // Submenus //FURI_LOG_D(TAG, "mifare_fuzzer_free() :: Submenus"); diff --git a/applications/external/nightstand/clock_app.c b/applications/external/nightstand/clock_app.c index eddc2b080..787352e93 100644 --- a/applications/external/nightstand/clock_app.c +++ b/applications/external/nightstand/clock_app.c @@ -365,4 +365,4 @@ int32_t clock_app(void* p) { notification_message(notif, &led_reset); return 0; -} +} \ No newline at end of file diff --git a/applications/external/nrf24batch/nrf24batch.c b/applications/external/nrf24batch/nrf24batch.c index a41de8210..1eb90c3c2 100644 --- a/applications/external/nrf24batch/nrf24batch.c +++ b/applications/external/nrf24batch/nrf24batch.c @@ -218,6 +218,21 @@ static void add_to_str_hex_bytes(char* out, uint8_t* arr, int bytes) { } while(--bytes); } +// skip leading zeros +static void add_to_str_hex_variable(char* out, uint8_t* arr, int size) { + if(size <= 0) return; + out += strlen(out); + arr += size - 1; + while(*arr == 0 && size > 1) { + arr--; + size--; + } + do { + snprintf(out, 3, "%02X", *arr--); + out += 2; + } while(--size); +} + void Edit_insert_digit(char new) { if(*Edit_pos == '-') return; if(what_doing <= 1) { @@ -506,7 +521,7 @@ bool nrf24_read_newpacket() { else { char hex[9]; hex[0] = '\0'; - add_to_str_hex_bytes(hex, (uint8_t*)&var, size); + add_to_str_hex_variable(hex, (uint8_t*)&var, size); if((cmd_array && cmd_array_hex) || furi_string_end_with_str(str, "0x")) furi_string_cat_str(str, hex); else { @@ -883,7 +898,7 @@ static uint8_t load_settings_file() { NRF_INITED = false; while(stream_read_line(file_stream, str)) { char* p = (char*)furi_string_get_cstr(str); - if(*p <= ' ') continue; + if(*p <= '!' || *p == ';') continue; //char* delim_eq = strchr(p, '='); char* delim_col = strchr(p, ':'); if(delim_col == NULL) { // Constant found - no ':' @@ -1288,12 +1303,12 @@ static void render_callback(Canvas* const canvas, void* ctx) { int32_t n = get_payload_receive_field(pld, len); if(hex) { strcat(screen_buf, "0x"); - add_to_str_hex_bytes(screen_buf, pld, len); + add_to_str_hex_variable(screen_buf, pld, len); } else { snprintf(screen_buf + strlen(screen_buf), 20, "%ld", n); if(n > 9) { strcat(screen_buf, " ("); - add_to_str_hex_bytes(screen_buf, pld, len); + add_to_str_hex_variable(screen_buf, pld, len); strcat(screen_buf, ")"); } } diff --git a/applications/external/passgen/application.fam b/applications/external/passgen/application.fam index ededadaec..6a9652dc1 100644 --- a/applications/external/passgen/application.fam +++ b/applications/external/passgen/application.fam @@ -6,7 +6,7 @@ App( requires=[ "gui", ], - fap_category="Misc", + fap_category="Tools", fap_icon="icons/passgen_icon.png", fap_icon_assets="icons", ) diff --git a/applications/external/passgen/passgen.c b/applications/external/passgen/passgen.c index be6656f7a..07a97a3c0 100644 --- a/applications/external/passgen/passgen.c +++ b/applications/external/passgen/passgen.c @@ -6,14 +6,14 @@ #include #include #include +#include #define PASSGEN_MAX_LENGTH 16 -#define PASSGEN_CHARACTERS_LENGTH (26 * 4) #define PASSGEN_DIGITS "0123456789" #define PASSGEN_LETTERS_LOW "abcdefghijklmnopqrstuvwxyz" #define PASSGEN_LETTERS_UP "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define PASSGEN_SPECIAL "!#$%^&*.-_" +#define PASSGEN_SPECIAL "!#$%%^&*.-_" typedef enum PassGen_Alphabet { Digits = 1, @@ -46,7 +46,8 @@ typedef struct { FuriMutex** mutex; NotificationApp* notify; char password[PASSGEN_MAX_LENGTH + 1]; - char alphabet[PASSGEN_CHARACTERS_LENGTH + 1]; + // char alphabet[PASSGEN_CHARACTERS_LENGTH + 1]; + FuriString* alphabet; int length; int level; } PassGen; @@ -58,6 +59,7 @@ void state_free(PassGen* app) { furi_message_queue_free(app->input_queue); furi_mutex_free(app->mutex); furi_record_close(RECORD_NOTIFICATION); + furi_string_free(app->alphabet); free(app); } @@ -99,17 +101,17 @@ static void render_callback(Canvas* canvas, void* ctx) { void build_alphabet(PassGen* app) { PassGen_Alphabet mode = AlphabetLevels[app->level]; - app->alphabet[0] = '\0'; - if((mode & Digits) != 0) strcat(app->alphabet, PASSGEN_DIGITS); - if((mode & Lowercase) != 0) strcat(app->alphabet, PASSGEN_LETTERS_LOW); - if((mode & Uppercase) != 0) strcat(app->alphabet, PASSGEN_LETTERS_UP); - if((mode & Special) != 0) strcat(app->alphabet, PASSGEN_SPECIAL); + if((mode & Digits) != 0) furi_string_cat(app->alphabet, PASSGEN_DIGITS); + if((mode & Lowercase) != 0) furi_string_cat(app->alphabet, PASSGEN_LETTERS_LOW); + if((mode & Uppercase) != 0) furi_string_cat(app->alphabet, PASSGEN_LETTERS_UP); + if((mode & Special) != 0) furi_string_cat(app->alphabet, PASSGEN_SPECIAL); } PassGen* state_init() { PassGen* app = malloc(sizeof(PassGen)); app->length = 8; app->level = 2; + app->alphabet = furi_string_alloc(); build_alphabet(app); app->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); app->view_port = view_port_alloc(); @@ -125,10 +127,10 @@ PassGen* state_init() { } void generate(PassGen* app) { - int hi = strlen(app->alphabet); + int hi = furi_string_size(app->alphabet); for(int i = 0; i < app->length; i++) { int x = rand() % hi; - app->password[i] = app->alphabet[x]; + app->password[i] = furi_string_get_char(app->alphabet, x); } app->password[app->length] = '\0'; } diff --git a/applications/external/pomodoro/application.fam b/applications/external/pomodoro/application.fam index e0d4e9ec0..a96870e09 100644 --- a/applications/external/pomodoro/application.fam +++ b/applications/external/pomodoro/application.fam @@ -5,11 +5,11 @@ App( entry_point="flipp_pomodoro_app", requires=["gui", "notification", "dolphin"], stack_size=1 * 1024, - fap_category="Misc", + fap_category="Tools", fap_icon_assets="images", fap_icon="flipp_pomodoro_10.png", fap_author="@Th3Un1q3", fap_weburl="https://github.com/Th3Un1q3/flipp_pomodoro", - fap_version="1.0", + fap_version="1.1", fap_description="Boost Your Productivity with the Pomodoro Timer", ) diff --git a/applications/external/pomodoro/flipp_pomodoro_app.c b/applications/external/pomodoro/flipp_pomodoro_app.c index 3ee3b0277..70f065e8b 100644 --- a/applications/external/pomodoro/flipp_pomodoro_app.c +++ b/applications/external/pomodoro/flipp_pomodoro_app.c @@ -1,5 +1,7 @@ #include "flipp_pomodoro_app_i.h" +#define TAG "FlippPomodoro" + enum { CustomEventConsumed = true, CustomEventNotConsumed = false, @@ -29,6 +31,14 @@ static bool flipp_pomodoro_app_custom_event_callback(void* ctx, uint32_t event) app->view_dispatcher, FlippPomodoroAppCustomEventStateUpdated); return CustomEventConsumed; case FlippPomodoroAppCustomEventStageComplete: + if(flipp_pomodoro__get_stage(app->state) == FlippPomodoroStageFocus) { + // REGISTER a deed on work stage complete to get an acheivement + // dolphin_deed(DolphinDeedPluginGameWin); + FURI_LOG_I(TAG, "Focus stage reward added"); + + flipp_pomodoro_statistics__increase_focus_stages_completed(app->statistics); + }; + flipp_pomodoro__toggle_stage(app->state); notification_message( app->notification_app, @@ -51,6 +61,8 @@ FlippPomodoroApp* flipp_pomodoro_app_alloc() { app->notification_app = furi_record_open(RECORD_NOTIFICATION); app->view_dispatcher = view_dispatcher_alloc(); + app->statistics = flipp_pomodoro_statistics__new(); + view_dispatcher_enable_queue(app->view_dispatcher); view_dispatcher_set_event_callback_context(app->view_dispatcher, app); view_dispatcher_set_custom_event_callback( @@ -62,22 +74,31 @@ FlippPomodoroApp* flipp_pomodoro_app_alloc() { app->view_dispatcher, flipp_pomodoro_app_back_event_callback); app->timer_view = flipp_pomodoro_view_timer_alloc(); + app->info_view = flipp_pomodoro_info_view_alloc(); view_dispatcher_add_view( app->view_dispatcher, FlippPomodoroAppViewTimer, flipp_pomodoro_view_timer_get_view(app->timer_view)); - scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer); + view_dispatcher_add_view( + app->view_dispatcher, + FlippPomodoroAppViewInfo, + flipp_pomodoro_info_view_get_view(app->info_view)); + scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer); + FURI_LOG_I(TAG, "Alloc complete"); return app; } void flipp_pomodoro_app_free(FlippPomodoroApp* app) { view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewTimer); + view_dispatcher_remove_view(app->view_dispatcher, FlippPomodoroAppViewInfo); view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); flipp_pomodoro_view_timer_free(app->timer_view); + flipp_pomodoro_info_view_free(app->info_view); + flipp_pomodoro_statistics__destroy(app->statistics); flipp_pomodoro__destroy(app->state); free(app); furi_record_close(RECORD_GUI); @@ -86,8 +107,12 @@ void flipp_pomodoro_app_free(FlippPomodoroApp* app) { int32_t flipp_pomodoro_app(void* p) { UNUSED(p); + FURI_LOG_I(TAG, "Initial"); FlippPomodoroApp* app = flipp_pomodoro_app_alloc(); + FURI_LOG_I(TAG, "Run deed added"); + // dolphin_deed(DolphinDeedPluginGameStart); + view_dispatcher_run(app->view_dispatcher); flipp_pomodoro_app_free(app); diff --git a/applications/external/pomodoro/flipp_pomodoro_app.h b/applications/external/pomodoro/flipp_pomodoro_app.h index 54102e1f3..fab9b0f9c 100644 --- a/applications/external/pomodoro/flipp_pomodoro_app.h +++ b/applications/external/pomodoro/flipp_pomodoro_app.h @@ -7,8 +7,10 @@ #include #include #include "views/flipp_pomodoro_timer_view.h" +#include "views/flipp_pomodoro_info_view.h" #include "modules/flipp_pomodoro.h" +#include "modules/flipp_pomodoro_statistics.h" typedef enum { // Reserve first 100 events for button types and indexes, starting from 0 @@ -16,6 +18,7 @@ typedef enum { FlippPomodoroAppCustomEventStageComplete, // By Expiration FlippPomodoroAppCustomEventTimerTick, FlippPomodoroAppCustomEventStateUpdated, + FlippPomodoroAppCustomEventResumeTimer, } FlippPomodoroAppCustomEvent; typedef struct { @@ -24,9 +27,12 @@ typedef struct { Gui* gui; NotificationApp* notification_app; FlippPomodoroTimerView* timer_view; + FlippPomodoroInfoView* info_view; FlippPomodoroState* state; + FlippPomodoroStatistics* statistics; } FlippPomodoroApp; typedef enum { FlippPomodoroAppViewTimer, + FlippPomodoroAppViewInfo, } FlippPomodoroAppView; \ No newline at end of file diff --git a/applications/external/pomodoro/flipp_pomodoro_app_i.h b/applications/external/pomodoro/flipp_pomodoro_app_i.h index 03c3dc894..c07968952 100644 --- a/applications/external/pomodoro/flipp_pomodoro_app_i.h +++ b/applications/external/pomodoro/flipp_pomodoro_app_i.h @@ -1,6 +1,6 @@ #pragma once -#define FURI_DEBUG 1 +// #define FURI_DEBUG 1 /** * Index of dependencies for the main app @@ -15,6 +15,7 @@ #include #include #include +#include #include // App resource imports diff --git a/applications/external/pomodoro/images/flipp_pomodoro_learn_50x128.png b/applications/external/pomodoro/images/flipp_pomodoro_learn_50x128.png new file mode 100644 index 0000000000000000000000000000000000000000..d32f62c1d051b97b6fadffe9bb5bf9c4a0d11268 GIT binary patch literal 1234 zcmV;@1TFiCP)Px(j7da6RCr$PT+x!_APj5&|D(H;yP-oJ%Mu3K3}Ih(HU$H=EDJ*S`FK2DkHpXG z^}pNm`TY00{EbYNcI9)_-?mey=8a$5isozAaQt1juWe`6!F;2xaYnl%dP@SJ4q|bf z7g+SHfZE#Wu{$Gxy*A$fP*Lh-OJ)*iJe5)Epdto}GTZjAnW+TXn+swU%NSm}+E0;f zH5M7a+dfMJz-E3614Jdj1}L)YF-9q!sBHZd0H_ADnxE}=LZs0YS-U6$m3q%KK%_T3 z;2;oqrD;S~x7au_zzB!e6JWrZ1%MVO{IYFbZoZlMZ}1fnXai-P!c;q}>B!zp0I1n+ z>p$A5c+W=!jWNVbfOazg6K#x9W&uD|>$V;Mnzo z7Ej5e+RmOwdZGsacK5=PX$AMH|x$DwAvm$pLu- zAm_JbdQkw_Z5!K%tLFqLv)Oa?^JOA5c_AABlO23@^QUc~ciG`sgt~8M?U4P^y8?Ei zcg(|kFQH!2u*bvE%O`KAgxc4Buyd^E7QHix+MO8O-U(a@0P5uocGl0{EFMmc0HO4+ z1H;}~c%Q4!AOKo3w^ik%_UgFoya8#Gn!UV0p=T%{_PM8#JTTaH2y_aNP_Uyh;CSdl z$f&bK{c zialU3&7f!iHHgugTeJXTkFq|b6%fl%FEvXkX^NALwF;I9pIqMM0;jcQ)Jz|?*rsK zw*ipz+cLd|-wCwLz|?(fjYmwf86bzr4S<~AmgzO@S~$vl!Iwg$*SYy%+YH`oikhGzEz22Vpa*L*3o^#st)M7`6C5XbHzYza^Ui`tdIme0NNX#r+! zZ2)wKRX5-Ppze*%3L>B=LH7jc8#J^3T|C<*AoqE+8M*pu>e`#@Xa-WR=ASiAA07WKR+Ei@cY5)KL07*qoM6N<$f-LDlVE_OC literal 0 HcmV?d00001 diff --git a/applications/external/pomodoro/modules/flipp_pomodoro.h b/applications/external/pomodoro/modules/flipp_pomodoro.h index 251a77469..a1e50cb6e 100644 --- a/applications/external/pomodoro/modules/flipp_pomodoro.h +++ b/applications/external/pomodoro/modules/flipp_pomodoro.h @@ -12,7 +12,6 @@ typedef enum { /// @brief State of the pomodoro timer typedef struct { - PomodoroStage stage; uint8_t current_stage_index; uint32_t started_at_timestamp; } FlippPomodoroState; diff --git a/applications/external/pomodoro/modules/flipp_pomodoro_statistics.c b/applications/external/pomodoro/modules/flipp_pomodoro_statistics.c new file mode 100644 index 000000000..4bc5bf56f --- /dev/null +++ b/applications/external/pomodoro/modules/flipp_pomodoro_statistics.c @@ -0,0 +1,26 @@ +#include "flipp_pomodoro_statistics.h" + +FlippPomodoroStatistics* flipp_pomodoro_statistics__new() { + FlippPomodoroStatistics* statistics = malloc(sizeof(FlippPomodoroStatistics)); + + statistics->focus_stages_completed = 0; + + return statistics; +} + +// Return the number of completed focus stages +uint8_t + flipp_pomodoro_statistics__get_focus_stages_completed(FlippPomodoroStatistics* statistics) { + return statistics->focus_stages_completed; +} + +// Increase the number of completed focus stages by one +void flipp_pomodoro_statistics__increase_focus_stages_completed( + FlippPomodoroStatistics* statistics) { + statistics->focus_stages_completed++; +} + +void flipp_pomodoro_statistics__destroy(FlippPomodoroStatistics* statistics) { + furi_assert(statistics); + free(statistics); +}; diff --git a/applications/external/pomodoro/modules/flipp_pomodoro_statistics.h b/applications/external/pomodoro/modules/flipp_pomodoro_statistics.h new file mode 100644 index 000000000..cfc843147 --- /dev/null +++ b/applications/external/pomodoro/modules/flipp_pomodoro_statistics.h @@ -0,0 +1,45 @@ +#pragma once +#include + +/** @brief FlippPomodoroStatistics structure + * + * This structure is used to keep track of completed focus stages. + */ +typedef struct { + uint8_t focus_stages_completed; +} FlippPomodoroStatistics; + +/** @brief Allocate and initialize a new FlippPomodoroStatistics + * + * This function allocates a new FlippPomodoroStatistics structure, initializes its members + * and returns a pointer to it. + * + * @return A pointer to a new FlippPomodoroStatistics structure + */ +FlippPomodoroStatistics* flipp_pomodoro_statistics__new(); + +/** @brief Get the number of completed focus stages + * + * This function retrieves the number of completed focus stages in a FlippPomodoroStatistics structure. + * + * @param statistics A pointer to a FlippPomodoroStatistics structure + * @return The number of completed focus stages + */ +uint8_t flipp_pomodoro_statistics__get_focus_stages_completed(FlippPomodoroStatistics* statistics); + +/** @brief Increase the number of completed focus stages + * + * This function increases the count of the completed focus stages by one in a FlippPomodoroStatistics structure. + * + * @param statistics A pointer to a FlippPomodoroStatistics structure + */ +void flipp_pomodoro_statistics__increase_focus_stages_completed( + FlippPomodoroStatistics* statistics); + +/** @brief Free a FlippPomodoroStatistics structure + * + * This function frees the memory used by a FlippPomodoroStatistics structure. + * + * @param statistics A pointer to a FlippPomodoroStatistics structure + */ +void flipp_pomodoro_statistics__destroy(FlippPomodoroStatistics* state); \ No newline at end of file diff --git a/applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h b/applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h index f95daeb30..5a83fb021 100644 --- a/applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h +++ b/applications/external/pomodoro/scenes/config/flipp_pomodoro_scene_config.h @@ -1 +1,2 @@ +ADD_SCENE(flipp_pomodoro, info, Info) ADD_SCENE(flipp_pomodoro, timer, Timer) \ No newline at end of file diff --git a/applications/external/pomodoro/scenes/flipp_pomodoro_scene.h b/applications/external/pomodoro/scenes/flipp_pomodoro_scene.h index 3b8a9052a..708d8f8e4 100644 --- a/applications/external/pomodoro/scenes/flipp_pomodoro_scene.h +++ b/applications/external/pomodoro/scenes/flipp_pomodoro_scene.h @@ -1,3 +1,4 @@ +#pragma once #include // Generate scene id and total number diff --git a/applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c b/applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c new file mode 100644 index 000000000..9d73108f8 --- /dev/null +++ b/applications/external/pomodoro/scenes/flipp_pomodoro_scene_info.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include "flipp_pomodoro_scene.h" +#include "../flipp_pomodoro_app.h" +#include "../views/flipp_pomodoro_info_view.h" + +enum { SceneEventConusmed = true, SceneEventNotConusmed = false }; + +void flipp_pomodoro_scene_info_on_back_to_timer(void* ctx) { + furi_assert(ctx); + FlippPomodoroApp* app = ctx; + + view_dispatcher_send_custom_event( + app->view_dispatcher, FlippPomodoroAppCustomEventResumeTimer); +}; + +void flipp_pomodoro_scene_info_on_enter(void* ctx) { + furi_assert(ctx); + FlippPomodoroApp* app = ctx; + + view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewInfo); + flipp_pomodoro_info_view_set_pomodoros_completed( + flipp_pomodoro_info_view_get_view(app->info_view), + flipp_pomodoro_statistics__get_focus_stages_completed(app->statistics)); + flipp_pomodoro_info_view_set_mode( + flipp_pomodoro_info_view_get_view(app->info_view), FlippPomodoroInfoViewModeStats); + flipp_pomodoro_info_view_set_resume_timer_cb( + app->info_view, flipp_pomodoro_scene_info_on_back_to_timer, app); +}; + +void flipp_pomodoro_scene_info_handle_custom_event( + FlippPomodoroApp* app, + FlippPomodoroAppCustomEvent custom_event) { + if(custom_event == FlippPomodoroAppCustomEventResumeTimer) { + scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneTimer); + } +}; + +bool flipp_pomodoro_scene_info_on_event(void* ctx, SceneManagerEvent event) { + furi_assert(ctx); + FlippPomodoroApp* app = ctx; + + switch(event.type) { + case SceneManagerEventTypeBack: + view_dispatcher_stop(app->view_dispatcher); + return SceneEventConusmed; + case SceneManagerEventTypeCustom: + flipp_pomodoro_scene_info_handle_custom_event(app, event.event); + return SceneEventConusmed; + default: + break; + }; + return SceneEventNotConusmed; +}; + +void flipp_pomodoro_scene_info_on_exit(void* ctx) { + UNUSED(ctx); +}; \ No newline at end of file diff --git a/applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c b/applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c index 8ed5dd5e7..20fb3c449 100644 --- a/applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c +++ b/applications/external/pomodoro/scenes/flipp_pomodoro_scene_timer.c @@ -1,13 +1,13 @@ #include #include #include +#include +#include "flipp_pomodoro_scene.h" #include "../flipp_pomodoro_app.h" #include "../views/flipp_pomodoro_timer_view.h" enum { SceneEventConusmed = true, SceneEventNotConusmed = false }; -uint8_t ExitSignal = 0; - void flipp_pomodoro_scene_timer_sync_view_state(void* ctx) { furi_assert(ctx); @@ -30,6 +30,11 @@ void flipp_pomodoro_scene_timer_on_enter(void* ctx) { FlippPomodoroApp* app = ctx; + if(flipp_pomodoro__is_stage_expired(app->state)) { + flipp_pomodoro__destroy(app->state); + app->state = flipp_pomodoro__new(); + } + view_dispatcher_switch_to_view(app->view_dispatcher, FlippPomodoroAppViewTimer); flipp_pomodoro_scene_timer_sync_view_state(app); flipp_pomodoro_view_timer_set_on_right_cb( @@ -59,7 +64,8 @@ bool flipp_pomodoro_scene_timer_on_event(void* ctx, SceneManagerEvent event) { flipp_pomodoro_scene_timer_handle_custom_event(app, event.event); return SceneEventConusmed; case SceneManagerEventTypeBack: - return ExitSignal; + scene_manager_next_scene(app->scene_manager, FlippPomodoroSceneInfo); + return SceneEventConusmed; default: break; } diff --git a/applications/external/pomodoro/views/flipp_pomodoro_info_view.c b/applications/external/pomodoro/views/flipp_pomodoro_info_view.c new file mode 100644 index 000000000..dab23ab9e --- /dev/null +++ b/applications/external/pomodoro/views/flipp_pomodoro_info_view.c @@ -0,0 +1,152 @@ + +#include +#include +#include +#include +#include "flipp_pomodoro_info_view.h" +// Auto-compiled icons +#include "flipp_pomodoro_icons.h" + +enum { + ViewInputConsumed = true, + ViewInputNotConusmed = false, +}; + +struct FlippPomodoroInfoView { + View* view; + FlippPomodoroInfoViewUserActionCb resume_timer_cb; + void* user_action_cb_ctx; +}; + +typedef struct { + uint8_t pomodoros_completed; + FlippPomodoroInfoViewMode mode; +} FlippPomodoroInfoViewModel; + +static void + flipp_pomodoro_info_view_draw_statistics(Canvas* canvas, FlippPomodoroInfoViewModel* model) { + FuriString* stats_string = furi_string_alloc(); + + furi_string_printf( + stats_string, + "So Long,\nand Thanks for All the Focus...\nand for completing\n%i pomodoro(s)", + model->pomodoros_completed); + const char* stats_string_formatted = furi_string_get_cstr(stats_string); + + elements_text_box( + canvas, + 0, + 0, + canvas_width(canvas), + canvas_height(canvas) - 10, + AlignCenter, + AlignCenter, + stats_string_formatted, + true); + + furi_string_free(stats_string); + + elements_button_left(canvas, "Guide"); +} + +static void + flipp_pomodoro_info_view_draw_about(Canvas* canvas, FlippPomodoroInfoViewModel* model) { + UNUSED(model); + canvas_draw_icon(canvas, 0, 0, &I_flipp_pomodoro_learn_50x128); + elements_button_left(canvas, "Stats"); +} + +static void flipp_pomodoro_info_view_draw_callback(Canvas* canvas, void* _model) { + if(!_model) { + return; + }; + + FlippPomodoroInfoViewModel* model = _model; + + canvas_clear(canvas); + + if(model->mode == FlippPomodoroInfoViewModeStats) { + flipp_pomodoro_info_view_draw_statistics(canvas, model); + } else { + flipp_pomodoro_info_view_draw_about(canvas, model); + } + + elements_button_right(canvas, "Resume"); +} + +void flipp_pomodoro_info_view_set_mode(View* view, FlippPomodoroInfoViewMode desired_mode) { + with_view_model( + view, FlippPomodoroInfoViewModel * model, { model->mode = desired_mode; }, false); +} + +void flipp_pomodoro_info_view_toggle_mode(FlippPomodoroInfoView* info_view) { + with_view_model( + flipp_pomodoro_info_view_get_view(info_view), + FlippPomodoroInfoViewModel * model, + { + flipp_pomodoro_info_view_set_mode( + flipp_pomodoro_info_view_get_view(info_view), + (model->mode == FlippPomodoroInfoViewModeStats) ? FlippPomodoroInfoViewModeAbout : + FlippPomodoroInfoViewModeStats); + }, + true); +} + +bool flipp_pomodoro_info_view_input_callback(InputEvent* event, void* ctx) { + FlippPomodoroInfoView* info_view = ctx; + + if(event->type == InputTypePress) { + if(event->key == InputKeyRight && info_view->resume_timer_cb != NULL) { + info_view->resume_timer_cb(info_view->user_action_cb_ctx); + return ViewInputConsumed; + } else if(event->key == InputKeyLeft) { + flipp_pomodoro_info_view_toggle_mode(info_view); + return ViewInputConsumed; + } + } + + return ViewInputNotConusmed; +} + +FlippPomodoroInfoView* flipp_pomodoro_info_view_alloc() { + FlippPomodoroInfoView* info_view = malloc(sizeof(FlippPomodoroInfoView)); + info_view->view = view_alloc(); + + view_allocate_model( + flipp_pomodoro_info_view_get_view(info_view), + ViewModelTypeLockFree, + sizeof(FlippPomodoroInfoViewModel)); + view_set_context(flipp_pomodoro_info_view_get_view(info_view), info_view); + view_set_draw_callback( + flipp_pomodoro_info_view_get_view(info_view), flipp_pomodoro_info_view_draw_callback); + view_set_input_callback( + flipp_pomodoro_info_view_get_view(info_view), flipp_pomodoro_info_view_input_callback); + + return info_view; +} + +View* flipp_pomodoro_info_view_get_view(FlippPomodoroInfoView* info_view) { + return info_view->view; +} + +void flipp_pomodoro_info_view_free(FlippPomodoroInfoView* info_view) { + furi_assert(info_view); + view_free(info_view->view); + free(info_view); +} + +void flipp_pomodoro_info_view_set_pomodoros_completed(View* view, uint8_t pomodoros_completed) { + with_view_model( + view, + FlippPomodoroInfoViewModel * model, + { model->pomodoros_completed = pomodoros_completed; }, + false); +} + +void flipp_pomodoro_info_view_set_resume_timer_cb( + FlippPomodoroInfoView* info_view, + FlippPomodoroInfoViewUserActionCb user_action_cb, + void* user_action_cb_ctx) { + info_view->resume_timer_cb = user_action_cb; + info_view->user_action_cb_ctx = user_action_cb_ctx; +} diff --git a/applications/external/pomodoro/views/flipp_pomodoro_info_view.h b/applications/external/pomodoro/views/flipp_pomodoro_info_view.h new file mode 100644 index 000000000..dd289a4d8 --- /dev/null +++ b/applications/external/pomodoro/views/flipp_pomodoro_info_view.h @@ -0,0 +1,71 @@ +#pragma once + +#include + +/** @brief Mode types for FlippPomodoroInfoView + * + * These are the modes that can be used in the FlippPomodoroInfoView + */ +typedef enum { + FlippPomodoroInfoViewModeStats, + FlippPomodoroInfoViewModeAbout, +} FlippPomodoroInfoViewMode; + +/** @brief Forward declaration of the FlippPomodoroInfoView struct */ +typedef struct FlippPomodoroInfoView FlippPomodoroInfoView; + +/** @brief User action callback function type + * + * Callback functions of this type are called when a user action is performed. + */ +typedef void (*FlippPomodoroInfoViewUserActionCb)(void* ctx); + +/** @brief Allocate a new FlippPomodoroInfoView + * + * Allocates a new FlippPomodoroInfoView and returns a pointer to it. + * @return A pointer to a new FlippPomodoroInfoView + */ +FlippPomodoroInfoView* flipp_pomodoro_info_view_alloc(); + +/** @brief Get the view from a FlippPomodoroInfoView + * + * Returns a pointer to the view associated with a FlippPomodoroInfoView. + * @param info_view A pointer to a FlippPomodoroInfoView + * @return A pointer to the view of the FlippPomodoroInfoView + */ +View* flipp_pomodoro_info_view_get_view(FlippPomodoroInfoView* info_view); + +/** @brief Free a FlippPomodoroInfoView + * + * Frees the memory used by a FlippPomodoroInfoView. + * @param info_view A pointer to a FlippPomodoroInfoView + */ +void flipp_pomodoro_info_view_free(FlippPomodoroInfoView* info_view); + +/** @brief Set the number of completed pomodoros in the view + * + * Sets the number of completed pomodoros that should be displayed in the view. + * @param info_view A pointer to the view + * @param pomodoros_completed The number of completed pomodoros + */ +void flipp_pomodoro_info_view_set_pomodoros_completed(View* info_view, uint8_t pomodoros_completed); + +/** @brief Set the callback function to be called when the timer should be resumed + * + * Sets the callback function that will be called when the timer should be resumed. + * @param info_view A pointer to the FlippPomodoroInfoView + * @param user_action_cb The callback function + * @param user_action_cb_ctx The context to be passed to the callback function + */ +void flipp_pomodoro_info_view_set_resume_timer_cb( + FlippPomodoroInfoView* info_view, + FlippPomodoroInfoViewUserActionCb user_action_cb, + void* user_action_cb_ctx); + +/** @brief Set the mode of the view + * + * Sets the mode that should be used in the view. + * @param view A pointer to the view + * @param desired_mode The desired mode + */ +void flipp_pomodoro_info_view_set_mode(View* view, FlippPomodoroInfoViewMode desired_mode); diff --git a/applications/external/pomodoro/views/flipp_pomodoro_timer_view.c b/applications/external/pomodoro/views/flipp_pomodoro_timer_view.c index 302380ddd..eef96fcd1 100644 --- a/applications/external/pomodoro/views/flipp_pomodoro_timer_view.c +++ b/applications/external/pomodoro/views/flipp_pomodoro_timer_view.c @@ -156,7 +156,10 @@ FlippPomodoroTimerView* flipp_pomodoro_view_timer_alloc() { FlippPomodoroTimerView* timer = malloc(sizeof(FlippPomodoroTimerView)); timer->view = view_alloc(); - view_allocate_model(timer->view, ViewModelTypeLockFree, sizeof(FlippPomodoroTimerViewModel)); + view_allocate_model( + flipp_pomodoro_view_timer_get_view(timer), + ViewModelTypeLockFree, + sizeof(FlippPomodoroTimerViewModel)); view_set_context(flipp_pomodoro_view_timer_get_view(timer), timer); view_set_draw_callback(timer->view, flipp_pomodoro_view_timer_draw_callback); view_set_input_callback(timer->view, flipp_pomodoro_view_timer_input_callback); diff --git a/applications/external/pong/application.fam b/applications/external/pong/application.fam index 02dcfd675..97292e6c5 100644 --- a/applications/external/pong/application.fam +++ b/applications/external/pong/application.fam @@ -12,6 +12,6 @@ App( fap_category="Games", fap_author="@nmrr & @SimplyMinimal", fap_weburl="https://github.com/nmrr/flipperzero-pong", - fap_version="1.0", + fap_version="1.1", fap_description="Simple pong game", ) diff --git a/applications/external/pong/pong.png b/applications/external/pong/pong.png index 507ce711c0f97ee36d4c2d76800d0ba5463974da..b86745f289ba0a2c653ff6d13e68a8a515461252 100644 GIT binary patch literal 7315 zcmd5>Yitx%6rPImxJ@-mt7w{75R5fOXYZZ4Go#`Is8U0K0455ko!y-=jTjp!u>^dC z`T%QG@Rto54Zcu=(IO~HlvjxHN$@Qw5hFDQQ8c2W;CJrKcIUR+c3V_B&CcG}`Of#9 zbLLF4T{?C0m1XPvPR5 zZL3dQy}0W4l5g6-eX@Pjn8O!TuUYc*?pM#;|Kr#nzbYBGa?^~qn~s}mzcX=bCN0;U z``a6%?ku^>Y<_mjq_NAcfA_6HM{HU zzh7~1>G&5$S8v(7WzXR29{PRR4==xS%Zip0OD`7L?6hCDj7-1u*~Ym;+Lk|Y%9P>v zR$RSu(a0ZO-n5{lZRV<%J{kK*Y4d`c$GkVc^{geCVZ%m`9Ct-oFr#kdxaY69Z)y3y zZ5RKw`GHGo&wpfgV9q`7aaOT>&yXX{U+-$YdsVGdJz~)M8|EC!l(&C=LhJl54_~r& z-*>}y-!XXgnze6!VT6~~zPRp{pHBYp&9d3E*VzkBdUa>XJ&!fM{ZQrGQ>LF&e&<2) z=hKyDQ|a-a?EGrxA@??efAsNzvWAAC_g7Re+_h)dhDSI2z3}Oezdosa-`w{1`H)#i z$Ka`xX4D)xas@#AsbH!Z41jX{@=XahiW?Rm0p{!umNu zRpWw&peksp4-H0lRz(+=F0*XMm7bI)F3Yn#?qlH63>S?}Gi6%pt|svst!nG6V}oNu z;4FP`xe6NRbL**S9jDZl@-eb8jOWbF#2aaS!y^{BxQlfH&jH1b1To@RkL{Tk4+MF} zMk+q&$MU4-I!S5i_&hmL7oEe0(M>oC+f2nQI?pW!(aYL6BsdQQeBmwxX6nO*FH#H> zpB8Z_B`jJJj=B?V0=7Kp%QFpWoh}3^DVcR>r*sv{j_77Rg6m+#ly?(%E-a$17@ERU zDxD@GTs~ z(y^FKIWEtVAli?3B$vA6*6s2$;-5SZqXMsKg+)J9w2p9h^~YI-@7RT}TIHZ_pCbR1ekBdj?0$l#LG0 z;<)5u;oF{#xXeR-l@TLggTc7;gd;ZVbimS8qA$%g$)Yvv&oegl?w{ClN(5bA9`Lq;sg&V)Mx4v%?A@l+3OcYV76NESvaF^-3tC#SY@$RRE6oGH~m3wHQCU@rAg zq4G-4BN`C88ADx1n5ja?(ONxJjV&{_3kDQw3V=uyMVywnj`E%orbNC6)2IS-mUuzr zv?6TEOqnCO6m)b;J8G{Go)1ES7Ye;;IC@P-15qu6AnBR+EovSXTC@qzhz4qi+AXRs z*KmjzwLcd1KNz4elbgw&1Vc{*!W9|xh+H31Yx(Ab80Fh(F$Ue8XWe;7dhg6v?RApR zdeX0f6>Pb=R|F3`7)5Uh+EC_Q-eY?FqSPnvaUCU>`ZxZ6fbz-ho#p?-sCORu6P+0K zMNA%qMxB84&A!b3J)r)J(fR&+jC9<-%ycaSfsxL>PmFXiM**ap>a#vE(oOYQFF-ws z=@XECxTje!jCwNF_qqTTFQykDeY^Ns7e>XK>L&rzUol;P^o9P;j!Ifm%TWO(*&i#Q zq?jb10r?iu33i=zFGfFmtb(nxNX`l{DppJqX252xe_{rvw7ixAS<@*OJ3Dqjc`-WI zW5-D6k)IX8s5>!v5E>N$q#JZM`)`4Y6QgtcZyD*nikroZ`XfenFmR;hvTz|8{{e$4OgR7m literal 6459 zcmeHKdpuP879Wq0C_*Q3G)3L}ONN@P9soK05f-PIEUyQzfvUl_z z)CMpKzyX7a>y}A2lPx+*?W68A-S2u^>b2hC#Z~6n?&G0-Bc^pbYhL6mKDUar=go%v zfT4L&793%38X@_m^AcRJ-Oop?!(DdXh-=dwI6*mJorX`ZHfg+VbYs^bAMUZwIP*@P z&`nMAymaeGsdoQwLXE?*Sz(Q+&Qvv>X}$ck!?D*%-VBQ)-}f^#BBVJM8VYOP6NBS- z2k$0=CPjf#Ij8gDv(mK_bNF7Z7wVE@?QF?~d$P0!uRWXP&|J7{@W(T+`+90@bwgh3 z4dL?MyryIZI0P9#AwS>m@;G(C_(#QPYD-6^ea?nuaCNn@V_aQCs~c=vvKY+oY);sD>iF)M7Twt;aw|PNX~Vc- zidj5&_vS8a-ib`6DEq3PQ7Jk*-qOsPY;-rKr88~x$_tm4sg=ViZL2S0;{v7Td}~Sc z55_0}I&YlRs#nU?csuO95@#?-zHB(LYd_YcA!n`dQM+VgW2fYNki&xZC2Zr5+~h~+1{O>Hp4vyXvk#* zs(ZXP-hLp{=NHo*{Lp5_Tqn%K+J-6q>&CmdV~ZXn4;Gb-O#A6tz~ZK@IR#pctM<8V z!Ij_gaJ7lJ5i@Cd^y8w3@xEsAiutHJPhxA93Y!j}toGnao%Vb{JuNG^@yhJ5cs`r(J5nqvyk|F5H*1Y2HQOk6VzD znV43mx%tFUNo{pHD|x6qd2r1G(srlDxPnz;S3i?enejt8R)y^T)+~@=YcA14h;|lZ;E}-nn{JGv@ny zzZ!2mQcf66X>TY{wbIGIn>#%_wTZ&Dqow2Zm+l}K{uCrR$T{McP+nD@+_U&t@2sUp zhw3NPq1f}&vA55bB-*Uur)IkSqj~?Vrj=xKZKo_peZM+_-tjvVH0&!cHA{x^`fZ8&rw>;E zGlkk6UB?@nUOmt{R1tcMF}SlRntlvQNb=Uhh_45e7Wp(S6X5qLTwB4#Rnzi1nlWu_{1iclsENrW*OVy)#`c!+PR*^7zyWi=ZSj(pK-d2`Y>Emj8 zx{N(p_nAkh+}y$C`CKhrlbh;$o1$BA2XmbvWncDBUvkxJ)hv;B;QgG9>(T4b_)~`V zNelO%)S13g8sR>i(jA{6#wvc#2a1e$rr@2~u7J+}qk+ zCy)IavCO`1e$C523JQ8F)+KH#=^QYfqEatE{|6Z>`+nDzV+Nz!M2xFFf!Ep%H?Xhd zZ!L}}`Tep9D$lud+bSS>GFv#iWl_%-wE|P^0l5x`R{YEL^%aYL^j_UIz0tMb zm|ykg@B~Mocw|MZfuiN5UqYkLu;*Qewgr)$wRgK(2usTkS&dBJ*)C1$as15=g;Lun zaB||hIXQjU>5%;`H)b1~Q#a4NVa3t{3{F>WU^w1qH#RAmvC1TwJL8(}5mx51k#Qc= zwi|!vdanH5z4O7>&ou=4Yx_GIyg{vzNql76CXeni4ysp(Z>2>JSwucTt*^T5TLzhP zsh2ob9rI_Mw$WT+SZh$*-EgdaQH-bYj;H1;hMqoqfp083bLB0w*1ee*=Y`$_SAvEj z120h!>tRfXj;*`yGv>2Q$L}m-A5=abFngF#7rVz4Xf2BB&?)7HLZ`L{ws1EWChbrD z$-CO2^LTC4ma?Fd<6Z1m6P%dga8@rxd)ryePW1e^6dQNzy7?(fwi+AFX-``_tZiPy z!DlVAB1*7()lIf{YL9NXdprBp#qsnx#@ehEVXq-goqqML+2QM_-;{T1>ey-c2VGiG zq(RO*a3d&aP^Y_13tzG{`;7Loe$-p9N**WGc<-Yt595c(BL}g+Moy3&Jyk^=S~G$= zP*nUtUo6&1nPR>6cIWNoeN}JQ9&EciDWY9+sOrYE^C*;ojsQ7%1b8fBL85Rx$P)#_ zctyAvIhmkPb`AOr$|P z8VnL)`ezVc5&=@gVA$uQQbO?%C?b_kV$vZ#4kQ9h90exRa11_7#F0oaNaaB^IvJ*@ zpm-2#fk+Y#BH0&&gCQ_MEDTX8lv!YL1qwJUz*&Fqf&RT6F(DB~lp*qB8EVT3}3qf+=H@QY=jG7kWaPNEQLBr=IgBr*WnC!-~>WNZW^ zJV3;g$8ePiWg#>mDFKxe0s&CYLa>R*j0F&SDZV5Ui^yb=n6^YR>pkE{YmvlPBno3=lwqTlfvEf` z)gH()!UJXCU%>$Yi%feDr(6cmc1RDT8aV=~OeBd?iN@B3#qgT3)>t!4pjs5rXw~#) zfzTL7Qcw=_RGty6F%=XF3PWII9eh8NKF9@sQKi8UmCgj1WE{k&(Qys3?`05Wm0hzMlgh9l92QQL?*~!f;>7vA1kzv1pZecGJOFu zi%MaU{+}Tdc@RLQk#R6N7)BNdI)DQqDu^Rfi6EcPhXEqU_%bj5O^9ToFF;`dbQVDR zGK+QuGe!1h!pF_|eOVwW`8z-FXVl;60*(IWh2D&g zI%o*bUTC=3eD>_q7dIyzZe66OP@B_wYneInyMVz~gl#$mIZmndblKLO@gw%`B& diff --git a/applications/external/qrcode/application.fam b/applications/external/qrcode/application.fam index abf06041b..3aac3f18d 100644 --- a/applications/external/qrcode/application.fam +++ b/applications/external/qrcode/application.fam @@ -13,7 +13,7 @@ App( "gui", "dialogs", ], - fap_category="Misc", + fap_category="Tools", fap_icon="icons/qrcode_10px.png", fap_icon_assets="icons", ) diff --git a/applications/external/rubiks_cube_scrambler/application.fam b/applications/external/rubiks_cube_scrambler/application.fam index 8dee8e952..7193ae302 100644 --- a/applications/external/rubiks_cube_scrambler/application.fam +++ b/applications/external/rubiks_cube_scrambler/application.fam @@ -15,7 +15,7 @@ App( apptype=FlipperAppType.EXTERNAL, entry_point="rubiks_cube_scrambler_main", stack_size=1 * 1024, - fap_category="Misc", + fap_category="Games", fap_icon="cube.png", fap_author="@RaZeSloth", fap_weburl="https://github.com/RaZeSloth/flipperzero-rubiks-cube-scrambler", diff --git a/applications/external/scorched_tanks/application.fam b/applications/external/scorched_tanks/application.fam index 5bccead84..4d74c5ced 100644 --- a/applications/external/scorched_tanks/application.fam +++ b/applications/external/scorched_tanks/application.fam @@ -11,6 +11,6 @@ App( fap_category="Games", fap_author="@jasniec", fap_weburl="https://github.com/jasniec/flipper-scorched-tanks-game", - fap_version="1.0", - fap_description="A flipper zero game inspired by scorched earth.", + fap_version="1.1", + fap_description="A Flipper Zero game inspired by scorched earth", ) diff --git a/applications/external/scorched_tanks/scorchedTanks_10px.png b/applications/external/scorched_tanks/scorchedTanks_10px.png index 6e1ae4c04b973c4015b6c4bb84ee6e806c4cde04..a37b16cd6ab8f2d1b99158d3a51e8b62fd96c0e6 100644 GIT binary patch delta 146 zcmaFHGJ|D;q%ac$0|Qe)#482{#+poL=YY)Qi$Q^dIr_{0{W-#ix#sM9`Oq>k&G~wc1ViUZjdg_vUDvgr vo800l**>{8bJmkjWn3|FTuBu|tKOT3ZppayVYeb22 zer|4RUI~M9QEFmIYKlU6W=V#EyQgnJcq5-UP?4Rdi(`ny<=zRNTnq+0Or~G{$IqL` z)mn1VD)@k74_m+jFNNFdSeRC@Oj=TCbbasl_0m_S)ck#W<5}fWz4I?02)is%VOE&1 Q2V@_Er>mdKI;Vst05Awh-2eap diff --git a/applications/external/snake_2/snake_20.c b/applications/external/snake_2/snake_20.c index ccd623870..e56f38b71 100644 --- a/applications/external/snake_2/snake_20.c +++ b/applications/external/snake_2/snake_20.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -524,4 +525,4 @@ int32_t snake_20_app(void* p) { free(snake_state); return 0; -} +} \ No newline at end of file diff --git a/applications/external/solitaire/solitaire.c b/applications/external/solitaire/solitaire.c index f83a53575..1eb82cd6e 100644 --- a/applications/external/solitaire/solitaire.c +++ b/applications/external/solitaire/solitaire.c @@ -1,4 +1,5 @@ #include +#include #include #include #include "defines.h" @@ -571,4 +572,4 @@ free_and_exit: free(game_state); furi_message_queue_free(event_queue); return return_code; -} +} \ No newline at end of file diff --git a/applications/external/text2sam/stm32_sam.cpp b/applications/external/text2sam/stm32_sam.cpp index 16f6fcaab..c77543c03 100644 --- a/applications/external/text2sam/stm32_sam.cpp +++ b/applications/external/text2sam/stm32_sam.cpp @@ -5400,15 +5400,14 @@ void STM32SAM::sam( } } + if(i < 256) { + input[i] = phonetic ? '\x9b' : '['; + } + if(!phonetic) { - strncat(input, "[", 256); if(!TextToPhonemes((unsigned char*)input)) { - // PrintUsage(); return; } - - } else { - strncat(input, "\x9b", 256); } SetInput(input); diff --git a/applications/external/timelapse/application.fam b/applications/external/timelapse/application.fam index a6dc6ad33..cd1e2c408 100644 --- a/applications/external/timelapse/application.fam +++ b/applications/external/timelapse/application.fam @@ -1,5 +1,5 @@ App( - appid="timelapse", + appid="gpio_timelapse", name="[GPIO] Timelapse", apptype=FlipperAppType.EXTERNAL, entry_point="zeitraffer_app", diff --git a/applications/external/timelapse/zeitraffer.c b/applications/external/timelapse/zeitraffer.c index 4ffdba5f2..859d256ee 100644 --- a/applications/external/timelapse/zeitraffer.c +++ b/applications/external/timelapse/zeitraffer.c @@ -5,10 +5,11 @@ #include #include #include "gpio_item.h" -#include "timelapse_icons.h" +#include "gpio_timelapse_icons.h" #include -#define CONFIG_FILE_PATH APP_DATA_PATH("timelapse.conf") +#define CONFIG_FILE_DIRECTORY_PATH "/ext/apps_data/timelapse" +#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/timelapse.conf" // Часть кода покрадена из https://github.com/zmactep/flipperzero-hello-world @@ -153,6 +154,10 @@ int32_t zeitraffer_app(void* p) { FlipperFormat* load = flipper_format_file_alloc(storage); do { + if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) { + notification_message(notifications, &sequence_error); + break; + } if(!flipper_format_file_open_existing(load, CONFIG_FILE_PATH)) { notification_message(notifications, &sequence_error); break; diff --git a/applications/external/tuning_fork/tuning_fork.c b/applications/external/tuning_fork/tuning_fork.c index 5547fb670..3ff76fa9c 100644 --- a/applications/external/tuning_fork/tuning_fork.c +++ b/applications/external/tuning_fork/tuning_fork.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include diff --git a/applications/external/unitemp/application.fam b/applications/external/unitemp/application.fam index 3fbdd5185..260069f3e 100644 --- a/applications/external/unitemp/application.fam +++ b/applications/external/unitemp/application.fam @@ -9,6 +9,7 @@ App( stack_size=2 * 1024, order=100, fap_description="Universal temperature sensors reader", + fap_version="1.4", fap_author="@quen0n & (fixes by @xMasterX)", fap_weburl="https://github.com/quen0n/unitemp-flipperzero", fap_category="GPIO", diff --git a/applications/external/videopoker/poker.c b/applications/external/videopoker/poker.c index 0205d1319..20881529c 100644 --- a/applications/external/videopoker/poker.c +++ b/applications/external/videopoker/poker.c @@ -5,7 +5,6 @@ #include #include #include -#include "assets_icons.h" #include /* Core game logic from diff --git a/applications/external/wifi_marauder_companion/application.fam b/applications/external/wifi_marauder_companion/application.fam index 782f858d5..bfd23232c 100644 --- a/applications/external/wifi_marauder_companion/application.fam +++ b/applications/external/wifi_marauder_companion/application.fam @@ -9,21 +9,21 @@ App( fap_icon="wifi_10px.png", fap_category="WiFi", fap_private_libs=[ - Lib( - name="esp-serial-flasher", - fap_include_paths=["include"], - sources=[ - "src/esp_loader.c", - "src/esp_targets.c", - "src/md5_hash.c", - "src/protocol_common.c", - "src/protocol_uart.c", - "src/slip.c" - ], - cincludes=["lib/esp-serial-flasher/private_include"], - cdefines=["SERIAL_FLASHER_INTERFACE_UART=1", "MD5_ENABLED=1"], - ), - ], + Lib( + name="esp-serial-flasher", + fap_include_paths=["include"], + sources=[ + "src/esp_loader.c", + "src/esp_targets.c", + "src/md5_hash.c", + "src/protocol_common.c", + "src/protocol_uart.c", + "src/slip.c", + ], + cincludes=["lib/esp-serial-flasher/private_include"], + cdefines=["SERIAL_FLASHER_INTERFACE_UART=1", "MD5_ENABLED=1"], + ), + ], cdefines=["SERIAL_FLASHER_INTERFACE_UART=1"], fap_icon_assets="assets", ) diff --git a/applications/external/wifi_scanner/application.fam b/applications/external/wifi_scanner/application.fam index b8a441a2e..14f06ff7a 100644 --- a/applications/external/wifi_scanner/application.fam +++ b/applications/external/wifi_scanner/application.fam @@ -5,7 +5,7 @@ App( entry_point="wifi_scanner_app", requires=["gui"], stack_size=2 * 1024, - order=70, + order=110, fap_icon="wifi_10px.png", fap_category="WiFi", fap_author="@SequoiaSan & @xMasterX",