From 6db3bb2b7113abb91f33f2829b54680198b51de2 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 12 Oct 2024 13:37:04 +0800 Subject: [PATCH 01/20] long press calling detect --- applications/services/gui/modules/variable_item_list.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 934972a534..e23295ce0f 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -285,6 +285,9 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) default: break; } + } else if(event->type == InputTypeLong) { + variable_item_list_process_ok_long(variable_item_list); + consumed = true; } return consumed; @@ -413,6 +416,11 @@ void variable_item_list_process_ok(VariableItemList* variable_item_list) { true); } +void variable_item_list_process_ok_long(VariableItemList* variable_item_list) { + UNUSED(variable_item_list); + FURI_LOG_I("variable_item_list", "variable_item_list_process_ok_long call"); +} + static void variable_item_list_scroll_timer_callback(void* context) { furi_assert(context); VariableItemList* variable_item_list = context; From 72b30b806e0cf12226244b3178f938c04764e8f0 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 12 Oct 2024 14:57:49 +0800 Subject: [PATCH 02/20] PoC --- .../services/gui/modules/variable_item_list.c | 63 ++++++++++++++++++- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index e23295ce0f..3e510c7139 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -39,11 +39,25 @@ typedef struct { bool locked_message_visible; } VariableItemListModel; +typedef struct { + VariableItemList* variable_item_list; + VariableItem* item; + uint8_t current_page; + uint8_t option_1_index; + uint8_t option_2_index; + uint8_t option_3_index; + uint8_t option_4_index; + uint8_t selected_option_index; + uint8_t total_options; + uint8_t total_pages; +} OptionMenu; + static void variable_item_list_process_up(VariableItemList* variable_item_list); static void variable_item_list_process_down(VariableItemList* variable_item_list); static void variable_item_list_process_left(VariableItemList* variable_item_list); static void variable_item_list_process_right(VariableItemList* variable_item_list); static void variable_item_list_process_ok(VariableItemList* variable_item_list); +static void variable_item_list_process_ok_long(VariableItemList* variable_item_list); static size_t variable_item_list_items_on_screen(VariableItemListModel* model) { size_t res = 4; @@ -286,8 +300,13 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) break; } } else if(event->type == InputTypeLong) { - variable_item_list_process_ok_long(variable_item_list); - consumed = true; + switch(event->key) { + case InputKeyOk: + variable_item_list_process_ok_long(variable_item_list); + break; + default: + break; + } } return consumed; @@ -417,8 +436,46 @@ void variable_item_list_process_ok(VariableItemList* variable_item_list) { } void variable_item_list_process_ok_long(VariableItemList* variable_item_list) { - UNUSED(variable_item_list); FURI_LOG_I("variable_item_list", "variable_item_list_process_ok_long call"); + furi_check(variable_item_list); + + with_view_model( + variable_item_list->view, + VariableItemListModel * model, + { + VariableItem* item = variable_item_list_get_selected_item(model); + FURI_LOG_I("variable_item_list", "hight-field: %s", furi_string_get_cstr(item->label)); + FURI_LOG_I("variable_item_list", "sel-d: %d", item->current_value_index); + FURI_LOG_I( + "variable_item_list", "sel-t: %s", furi_string_get_cstr(item->current_value_text)); + FURI_LOG_I("variable_item_list", "in-tot: %d", item->values_count); + + FURI_LOG_I("variable_item_list", "all:"); + uint8_t original_index = item->current_value_index; + FURI_LOG_I("variable_item_list", "org-i: %d", original_index); + for(uint8_t i = 0; i < item->values_count; i++) { + item->current_value_index = i; + if(item->change_callback) { + item->change_callback(item); + } + FURI_LOG_I( + "variable_item_list", + " op- %d: %s", + i, + furi_string_get_cstr(item->current_value_text)); + } + // // reset + // item->current_value_index = original_index; + // if(item->change_callback) { + // item->change_callback(item); + // } + //test assign to 0 + item->current_value_index = 0; + if(item->change_callback) { + item->change_callback(item); + } + }, + true); } static void variable_item_list_scroll_timer_callback(void* context) { From adc403ceb432086b0a567c5c8bd04396c626c2e2 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 12 Oct 2024 16:46:32 +0800 Subject: [PATCH 03/20] full-PoC --- .../services/gui/modules/variable_item_list.c | 234 ++++++++++++++---- 1 file changed, 188 insertions(+), 46 deletions(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 3e510c7139..cbd74ff324 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -29,6 +29,14 @@ struct VariableItemList { FuriTimer* locked_timer; }; +typedef struct { + VariableItem* item; + uint8_t current_page; + uint8_t selected_option_index; + uint8_t total_options; + uint8_t total_pages; +} ZapperMenu; + typedef struct { VariableItemArray_t items; uint8_t position; @@ -37,20 +45,13 @@ typedef struct { FuriString* header; size_t scroll_counter; bool locked_message_visible; + + /// option menu + bool is_zapper_menu_active; + ZapperMenu zapper_menu; } VariableItemListModel; -typedef struct { - VariableItemList* variable_item_list; - VariableItem* item; - uint8_t current_page; - uint8_t option_1_index; - uint8_t option_2_index; - uint8_t option_3_index; - uint8_t option_4_index; - uint8_t selected_option_index; - uint8_t total_options; - uint8_t total_pages; -} OptionMenu; +static const char* allow_zapper_field[] = {"Frequency", "Modulation"}; static void variable_item_list_process_up(VariableItemList* variable_item_list); static void variable_item_list_process_down(VariableItemList* variable_item_list); @@ -64,8 +65,82 @@ static size_t variable_item_list_items_on_screen(VariableItemListModel* model) { return (furi_string_empty(model->header)) ? res : res - 1; } +static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { + // TODO: ugly now + ZapperMenu* zapper_menu = &model->zapper_menu; + VariableItem* item = zapper_menu->item; + + const uint8_t item_height = 16; + uint8_t item_width = canvas_width(canvas) - 5; + + canvas_clear(canvas); + canvas_set_font(canvas, FontSecondary); + + uint8_t start_option = zapper_menu->current_page * 4; + uint8_t end_option = start_option + 4; + if(end_option > zapper_menu->total_options) { + end_option = zapper_menu->total_options; + } + + uint8_t original_index = item->current_value_index; + + for(uint8_t i = start_option; i < end_option; i++) { + uint8_t item_position = i - start_option; + uint8_t item_y = item_position * item_height; + uint8_t item_text_y = item_y + item_height - 4; + + // TODO: maybe not need highlight since we choose by ^ v < > + if(item_position == zapper_menu->selected_option_index) { + canvas_set_color(canvas, ColorBlack); + elements_slightly_rounded_box(canvas, 0, item_y + 1, item_width, item_height - 2); + canvas_set_color(canvas, ColorWhite); + } else { + canvas_set_color(canvas, ColorBlack); + } + + // temp set current_value_index to use change_callback to get option text (TODO: find a better way, or maybe this is hardless as long as it only tune freq when back to receive page in subghz (need check)) + item->current_value_index = i; + if(item->change_callback) { + item->change_callback(item); + } + const char* option_text = furi_string_get_cstr(item->current_value_text); + + // paint + canvas_draw_str(canvas, 6, item_text_y, option_text); + } + + // reset current_value_index + item->current_value_index = original_index; + if(item->change_callback) { + item->change_callback(item); + } + + // pager : TODO POSITION + char page_info[16]; + snprintf( + page_info, + sizeof(page_info), + "Page %d/%d", + zapper_menu->current_page + 1, + zapper_menu->total_pages); + canvas_draw_str_aligned( + canvas, + canvas_width(canvas) / 2, + canvas_height(canvas) - 10, + AlignCenter, + AlignBottom, + page_info); +} + static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { VariableItemListModel* model = _model; + canvas_clear(canvas); + + if(model->is_zapper_menu_active) { + // paint + zapper_menu_draw(canvas, model); + return; + } const uint8_t item_height = 16; uint8_t item_width = canvas_width(canvas) - 5; @@ -234,6 +309,64 @@ void variable_item_list_set_header(VariableItemList* variable_item_list, const c true); } +static bool zapper_menu_input_handler(InputEvent* event, void* context) { + VariableItemList* variable_item_list = context; + bool consumed = true; + + with_view_model( + variable_item_list->view, + VariableItemListModel * model, + { + ZapperMenu* zapper_menu = &model->zapper_menu; + VariableItem* item = zapper_menu->item; + + if(event->type == InputTypeShort || event->type == InputTypeRepeat) { + uint8_t selected_option = 0xFF; // 初始化为无效值 + switch(event->key) { + case InputKeyUp: + selected_option = zapper_menu->current_page * 4 + 0; + break; + case InputKeyLeft: + selected_option = zapper_menu->current_page * 4 + 1; + break; + case InputKeyRight: + selected_option = zapper_menu->current_page * 4 + 2; + break; + case InputKeyDown: + selected_option = zapper_menu->current_page * 4 + 3; + break; + case InputKeyOk: + // paging + zapper_menu->current_page = + (zapper_menu->current_page + 1) % zapper_menu->total_pages; + // reset sel-ed one + zapper_menu->selected_option_index = 0; + break; + case InputKeyBack: + // exit + model->is_zapper_menu_active = false; + break; + default: + break; + } + + // check valid + if(selected_option != 0xFF && selected_option < zapper_menu->total_options) { //0xFF use as nullptr + // update anf callback + item->current_value_index = selected_option; + if(item->change_callback) { + item->change_callback(item); + } + // exit + model->is_zapper_menu_active = false; + } + } + }, + true); + + return consumed; +} + static bool variable_item_list_input_callback(InputEvent* event, void* context) { VariableItemList* variable_item_list = context; furi_assert(variable_item_list); @@ -243,7 +376,13 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) with_view_model( variable_item_list->view, VariableItemListModel * model, - { locked_message_visible = model->locked_message_visible; }, + { + if(model->is_zapper_menu_active) { + consumed = zapper_menu_input_handler(event, context); + } else { + locked_message_visible = model->locked_message_visible; + } + }, false); if((event->type != InputTypePress && event->type != InputTypeRelease) && @@ -302,8 +441,29 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) } else if(event->type == InputTypeLong) { switch(event->key) { case InputKeyOk: - variable_item_list_process_ok_long(variable_item_list); - break; + with_view_model( + variable_item_list->view, + VariableItemListModel * model, + { + VariableItem* item = VariableItemArray_get(model->items, model->position); + const char* label = furi_string_get_cstr(item->label); + + bool allowed = false; + for(size_t i = 0; i < sizeof(allow_zapper_field) / sizeof(char*); i++) { + if(strcmp(label, allow_zapper_field[i]) == 0) { + allowed = true; + break; + } + } + + if(!allowed) { + return false; + } + }, + false); //TODO: wrong logic here, allowed should pass back + variable_item_list_process_ok_long(variable_item_list); + //fallthrough + default: break; } @@ -436,7 +596,6 @@ void variable_item_list_process_ok(VariableItemList* variable_item_list) { } void variable_item_list_process_ok_long(VariableItemList* variable_item_list) { - FURI_LOG_I("variable_item_list", "variable_item_list_process_ok_long call"); furi_check(variable_item_list); with_view_model( @@ -444,36 +603,19 @@ void variable_item_list_process_ok_long(VariableItemList* variable_item_list) { VariableItemListModel * model, { VariableItem* item = variable_item_list_get_selected_item(model); - FURI_LOG_I("variable_item_list", "hight-field: %s", furi_string_get_cstr(item->label)); - FURI_LOG_I("variable_item_list", "sel-d: %d", item->current_value_index); - FURI_LOG_I( - "variable_item_list", "sel-t: %s", furi_string_get_cstr(item->current_value_text)); - FURI_LOG_I("variable_item_list", "in-tot: %d", item->values_count); - - FURI_LOG_I("variable_item_list", "all:"); - uint8_t original_index = item->current_value_index; - FURI_LOG_I("variable_item_list", "org-i: %d", original_index); - for(uint8_t i = 0; i < item->values_count; i++) { - item->current_value_index = i; - if(item->change_callback) { - item->change_callback(item); - } - FURI_LOG_I( - "variable_item_list", - " op- %d: %s", - i, - furi_string_get_cstr(item->current_value_text)); - } - // // reset - // item->current_value_index = original_index; - // if(item->change_callback) { - // item->change_callback(item); - // } - //test assign to 0 - item->current_value_index = 0; - if(item->change_callback) { - item->change_callback(item); - } + + // ini + model->is_zapper_menu_active = true; + ZapperMenu* zapper_menu = &model->zapper_menu; + + zapper_menu->item = item; + zapper_menu->current_page = 0; + zapper_menu->selected_option_index = 0; + zapper_menu->total_options = item->values_count; + zapper_menu->total_pages = (zapper_menu->total_options + 3) / 4; + + // update + model->scroll_counter = 0; }, true); } From f3dde73e5942e10fcf8667b11ff86cbf30f51d79 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 12 Oct 2024 18:50:41 +0800 Subject: [PATCH 04/20] worked --- .../services/gui/modules/variable_item_list.c | 132 ++++++++++-------- 1 file changed, 75 insertions(+), 57 deletions(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index cbd74ff324..814b822025 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -46,7 +46,7 @@ typedef struct { size_t scroll_counter; bool locked_message_visible; - /// option menu + /// zapper menu bool is_zapper_menu_active; ZapperMenu zapper_menu; } VariableItemListModel; @@ -71,7 +71,7 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { VariableItem* item = zapper_menu->item; const uint8_t item_height = 16; - uint8_t item_width = canvas_width(canvas) - 5; + // uint8_t item_width = canvas_width(canvas) - 5; canvas_clear(canvas); canvas_set_font(canvas, FontSecondary); @@ -90,13 +90,13 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { uint8_t item_text_y = item_y + item_height - 4; // TODO: maybe not need highlight since we choose by ^ v < > - if(item_position == zapper_menu->selected_option_index) { - canvas_set_color(canvas, ColorBlack); - elements_slightly_rounded_box(canvas, 0, item_y + 1, item_width, item_height - 2); - canvas_set_color(canvas, ColorWhite); - } else { - canvas_set_color(canvas, ColorBlack); - } + // if(item_position == zapper_menu->selected_option_index) { + // canvas_set_color(canvas, ColorBlack); + // elements_slightly_rounded_box(canvas, 0, item_y + 1, item_width, item_height - 2); + // canvas_set_color(canvas, ColorWhite); + // } else { + canvas_set_color(canvas, ColorBlack); + // } // temp set current_value_index to use change_callback to get option text (TODO: find a better way, or maybe this is hardless as long as it only tune freq when back to receive page in subghz (need check)) item->current_value_index = i; @@ -115,21 +115,45 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { item->change_callback(item); } - // pager : TODO POSITION - char page_info[16]; - snprintf( - page_info, - sizeof(page_info), - "Page %d/%d", - zapper_menu->current_page + 1, - zapper_menu->total_pages); - canvas_draw_str_aligned( + // // pager : TODO find a better place to put this widget, disable for now + // char page_info[16]; + // snprintf( + // page_info, + // sizeof(page_info), + // "Page %d/%d", + // zapper_menu->current_page + 1, + // zapper_menu->total_pages); + // canvas_draw_str_aligned( + // canvas, + // canvas_width(canvas) / 2, + // canvas_height(canvas) - 10, + // AlignCenter, + // AlignBottom, + // page_info); + + const uint8_t arrow_size = 9; + const uint8_t arrow_x = canvas_width(canvas) - 9; + + // ^ + canvas_draw_triangle( + canvas, arrow_x, 16 - (16 - 9) / 2, arrow_size, arrow_size, CanvasDirectionBottomToTop); + + // < + canvas_draw_triangle( + canvas, arrow_x + 9 / 2, 24, arrow_size, arrow_size, CanvasDirectionRightToLeft); + + // > + canvas_draw_triangle( + canvas, arrow_x - 9 / 2, 40, arrow_size, arrow_size, CanvasDirectionLeftToRight); + + // v + canvas_draw_triangle( canvas, - canvas_width(canvas) / 2, - canvas_height(canvas) - 10, - AlignCenter, - AlignBottom, - page_info); + arrow_x, + 16 * 3 + 6, + arrow_size, + arrow_size, + CanvasDirectionTopToBottom); } static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { @@ -351,7 +375,8 @@ static bool zapper_menu_input_handler(InputEvent* event, void* context) { } // check valid - if(selected_option != 0xFF && selected_option < zapper_menu->total_options) { //0xFF use as nullptr + if(selected_option != 0xFF && + selected_option < zapper_menu->total_options) { //0xFF use as nullptr // update anf callback item->current_value_index = selected_option; if(item->change_callback) { @@ -385,6 +410,8 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) }, false); + if(consumed) return true; + if((event->type != InputTypePress && event->type != InputTypeRelease) && locked_message_visible) { with_view_model( @@ -441,29 +468,9 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) } else if(event->type == InputTypeLong) { switch(event->key) { case InputKeyOk: - with_view_model( - variable_item_list->view, - VariableItemListModel * model, - { - VariableItem* item = VariableItemArray_get(model->items, model->position); - const char* label = furi_string_get_cstr(item->label); - - bool allowed = false; - for(size_t i = 0; i < sizeof(allow_zapper_field) / sizeof(char*); i++) { - if(strcmp(label, allow_zapper_field[i]) == 0) { - allowed = true; - break; - } - } - - if(!allowed) { - return false; - } - }, - false); //TODO: wrong logic here, allowed should pass back - variable_item_list_process_ok_long(variable_item_list); - //fallthrough - + consumed = true; + variable_item_list_process_ok_long(variable_item_list); + break; default: break; } @@ -604,18 +611,29 @@ void variable_item_list_process_ok_long(VariableItemList* variable_item_list) { { VariableItem* item = variable_item_list_get_selected_item(model); - // ini - model->is_zapper_menu_active = true; - ZapperMenu* zapper_menu = &model->zapper_menu; + bool is_allowed = false; + for(size_t i = 0; i < sizeof(allow_zapper_field) / sizeof(allow_zapper_field[0]); + i++) { + if(strcmp(furi_string_get_cstr(item->label), allow_zapper_field[i]) == 0) { + is_allowed = true; + break; + } + } - zapper_menu->item = item; - zapper_menu->current_page = 0; - zapper_menu->selected_option_index = 0; - zapper_menu->total_options = item->values_count; - zapper_menu->total_pages = (zapper_menu->total_options + 3) / 4; + if(is_allowed) { + // ini + model->is_zapper_menu_active = true; + ZapperMenu* zapper_menu = &model->zapper_menu; - // update - model->scroll_counter = 0; + zapper_menu->item = item; + zapper_menu->current_page = 0; + zapper_menu->selected_option_index = 0; + zapper_menu->total_options = item->values_count; + zapper_menu->total_pages = (zapper_menu->total_options + 3) / 4; + + // update + model->scroll_counter = 0; + } }, true); } From 136d2e2aa39fea8da2d7106338d0035422ee57dd Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 12 Oct 2024 18:59:35 +0800 Subject: [PATCH 05/20] format --- applications/services/gui/modules/variable_item_list.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 814b822025..352c307161 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -148,12 +148,7 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { // v canvas_draw_triangle( - canvas, - arrow_x, - 16 * 3 + 6, - arrow_size, - arrow_size, - CanvasDirectionTopToBottom); + canvas, arrow_x, 16 * 3 + 6, arrow_size, arrow_size, CanvasDirectionTopToBottom); } static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { @@ -468,7 +463,7 @@ static bool variable_item_list_input_callback(InputEvent* event, void* context) } else if(event->type == InputTypeLong) { switch(event->key) { case InputKeyOk: - consumed = true; + consumed = true; variable_item_list_process_ok_long(variable_item_list); break; default: From ce620438eb040acd13a95d153928efe718149806 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sun, 13 Oct 2024 00:38:35 +0800 Subject: [PATCH 06/20] use english comments --- applications/services/gui/modules/variable_item_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 352c307161..20fa0ef141 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -340,7 +340,7 @@ static bool zapper_menu_input_handler(InputEvent* event, void* context) { VariableItem* item = zapper_menu->item; if(event->type == InputTypeShort || event->type == InputTypeRepeat) { - uint8_t selected_option = 0xFF; // 初始化为无效值 + uint8_t selected_option = 0xFF; // as nullptr switch(event->key) { case InputKeyUp: selected_option = zapper_menu->current_page * 4 + 0; From c9217b3b0f550afb0c8e64659c19aa0fcf98a40a Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sun, 13 Oct 2024 00:41:03 +0800 Subject: [PATCH 07/20] comments fix --- applications/services/gui/modules/variable_item_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 20fa0ef141..e8be965573 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -616,7 +616,7 @@ void variable_item_list_process_ok_long(VariableItemList* variable_item_list) { } if(is_allowed) { - // ini + // init model->is_zapper_menu_active = true; ZapperMenu* zapper_menu = &model->zapper_menu; From c5d244aa2268b130e3fb9730ef1615782d136136 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sun, 13 Oct 2024 11:32:53 +0800 Subject: [PATCH 08/20] fix keyback long press crash --- .../services/gui/modules/variable_item_list.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index e8be965573..bf9d22101d 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -339,7 +339,7 @@ static bool zapper_menu_input_handler(InputEvent* event, void* context) { ZapperMenu* zapper_menu = &model->zapper_menu; VariableItem* item = zapper_menu->item; - if(event->type == InputTypeShort || event->type == InputTypeRepeat) { + if(event->type == InputTypeShort) { uint8_t selected_option = 0xFF; // as nullptr switch(event->key) { case InputKeyUp: @@ -380,6 +380,16 @@ static bool zapper_menu_input_handler(InputEvent* event, void* context) { // exit model->is_zapper_menu_active = false; } + } else if(event->type == InputTypeRepeat) { + if(event->key == InputKeyLeft || event->key == InputKeyRight || + event->key == InputKeyUp || event->key == InputKeyDown) { + zapper_menu->current_page = + (zapper_menu->current_page + 1) % zapper_menu->total_pages; + }else if (event->key == InputKeyBack){ + model->is_zapper_menu_active = false; + } + }else if (event->type == InputTypeLong && event->key == InputKeyBack){ + model->is_zapper_menu_active = false; } }, true); From d1783e5d28aff7e1f35982df4b1b882b80541d96 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sun, 13 Oct 2024 12:01:24 +0800 Subject: [PATCH 09/20] fix OK long press when enter the zapper scenes --- .../services/gui/modules/variable_item_list.c | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index bf9d22101d..e2276929b4 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -331,6 +331,12 @@ void variable_item_list_set_header(VariableItemList* variable_item_list, const c static bool zapper_menu_input_handler(InputEvent* event, void* context) { VariableItemList* variable_item_list = context; bool consumed = true; + // this ok_ever_released var is for: prevent to trigger shuffing when first enter, because without that, would make muscle memory press not possible, + // because it would start shuffle when long pressed OK and entered zapper menu if user didn't release OK in time (consumed system seems didn't consider this kind of edge case). + // the static usage is because make it keeps life among func calls, + // otherwise it would be reseted to false each time enter this func, but each calls would make it false. + // it now seted back to false when exit zapper menu. + static bool ok_ever_released = false; with_view_model( variable_item_list->view, @@ -339,7 +345,9 @@ static bool zapper_menu_input_handler(InputEvent* event, void* context) { ZapperMenu* zapper_menu = &model->zapper_menu; VariableItem* item = zapper_menu->item; - if(event->type == InputTypeShort) { + if(event->type == InputTypeRelease && event->key == InputKeyOk) { + ok_ever_released = true; + } else if(event->type == InputTypeShort) { uint8_t selected_option = 0xFF; // as nullptr switch(event->key) { case InputKeyUp: @@ -363,6 +371,7 @@ static bool zapper_menu_input_handler(InputEvent* event, void* context) { break; case InputKeyBack: // exit + ok_ever_released = false; model->is_zapper_menu_active = false; break; default: @@ -378,17 +387,19 @@ static bool zapper_menu_input_handler(InputEvent* event, void* context) { item->change_callback(item); } // exit + ok_ever_released = false; model->is_zapper_menu_active = false; } } else if(event->type == InputTypeRepeat) { - if(event->key == InputKeyLeft || event->key == InputKeyRight || - event->key == InputKeyUp || event->key == InputKeyDown) { + if(event->key == InputKeyOk && ok_ever_released) { zapper_menu->current_page = (zapper_menu->current_page + 1) % zapper_menu->total_pages; - }else if (event->key == InputKeyBack){ + } else if(event->key == InputKeyBack) { + ok_ever_released = false; model->is_zapper_menu_active = false; } - }else if (event->type == InputTypeLong && event->key == InputKeyBack){ + } else if(event->type == InputTypeLong && event->key == InputKeyBack) { + ok_ever_released = false; model->is_zapper_menu_active = false; } }, From ee49407411964df2442461708e9cc1e1797d0eb7 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Mon, 14 Oct 2024 17:32:35 +0800 Subject: [PATCH 10/20] just paint tune --- .../services/gui/modules/variable_item_list.c | 67 +++++++------------ 1 file changed, 23 insertions(+), 44 deletions(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index e2276929b4..34c9c77de9 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -66,13 +66,9 @@ static size_t variable_item_list_items_on_screen(VariableItemListModel* model) { } static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { - // TODO: ugly now ZapperMenu* zapper_menu = &model->zapper_menu; VariableItem* item = zapper_menu->item; - const uint8_t item_height = 16; - // uint8_t item_width = canvas_width(canvas) - 5; - canvas_clear(canvas); canvas_set_font(canvas, FontSecondary); @@ -86,27 +82,15 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { for(uint8_t i = start_option; i < end_option; i++) { uint8_t item_position = i - start_option; - uint8_t item_y = item_position * item_height; - uint8_t item_text_y = item_y + item_height - 4; - - // TODO: maybe not need highlight since we choose by ^ v < > - // if(item_position == zapper_menu->selected_option_index) { - // canvas_set_color(canvas, ColorBlack); - // elements_slightly_rounded_box(canvas, 0, item_y + 1, item_width, item_height - 2); - // canvas_set_color(canvas, ColorWhite); - // } else { - canvas_set_color(canvas, ColorBlack); - // } - - // temp set current_value_index to use change_callback to get option text (TODO: find a better way, or maybe this is hardless as long as it only tune freq when back to receive page in subghz (need check)) + item->current_value_index = i; if(item->change_callback) { item->change_callback(item); } const char* option_text = furi_string_get_cstr(item->current_value_text); - // paint - canvas_draw_str(canvas, 6, item_text_y, option_text); + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, 4, item_position * 14 + 9 + (item_position + 1) * 1, option_text); } // reset current_value_index @@ -115,40 +99,35 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { item->change_callback(item); } - // // pager : TODO find a better place to put this widget, disable for now - // char page_info[16]; - // snprintf( - // page_info, - // sizeof(page_info), - // "Page %d/%d", - // zapper_menu->current_page + 1, - // zapper_menu->total_pages); - // canvas_draw_str_aligned( - // canvas, - // canvas_width(canvas) / 2, - // canvas_height(canvas) - 10, - // AlignCenter, - // AlignBottom, - // page_info); - - const uint8_t arrow_size = 9; - const uint8_t arrow_x = canvas_width(canvas) - 9; + //scroll bar + #define SCROLL_BAR_HEIGHT 0 + const uint8_t scroll_bar_y = canvas_height(canvas) - SCROLL_BAR_HEIGHT; + elements_scrollbar_horizontal(canvas, 0, scroll_bar_y, canvas_width(canvas), zapper_menu->current_page ,zapper_menu->total_pages); + + //frame + #define GAP_SIZE_PX 1 + #define FRAME_HEIGHT 14 + for(int i = 0; i < 4; i++) { + uint8_t y = i * (FRAME_HEIGHT + GAP_SIZE_PX); + canvas_draw_rframe(canvas, 0, y, canvas_width(canvas), FRAME_HEIGHT, 3); + } + + //arrow + #define ARROR_SIZE 8 + const uint8_t arrow_x = canvas_width(canvas) - 9; // ^ canvas_draw_triangle( - canvas, arrow_x, 16 - (16 - 9) / 2, arrow_size, arrow_size, CanvasDirectionBottomToTop); - + canvas, arrow_x, 16 - (16 - 9) / 2 - 3, ARROR_SIZE, ARROR_SIZE, CanvasDirectionBottomToTop); // < canvas_draw_triangle( - canvas, arrow_x + 9 / 2, 24, arrow_size, arrow_size, CanvasDirectionRightToLeft); - + canvas, arrow_x + 9 / 2, 24 - 2, ARROR_SIZE, ARROR_SIZE, CanvasDirectionRightToLeft); // > canvas_draw_triangle( - canvas, arrow_x - 9 / 2, 40, arrow_size, arrow_size, CanvasDirectionLeftToRight); - + canvas, arrow_x - 9 / 2 + 2, 40 - 4, ARROR_SIZE, ARROR_SIZE, CanvasDirectionLeftToRight); // v canvas_draw_triangle( - canvas, arrow_x, 16 * 3 + 6, arrow_size, arrow_size, CanvasDirectionTopToBottom); + canvas, arrow_x, 16 * 3 + 6 - 6, ARROR_SIZE, ARROR_SIZE, CanvasDirectionTopToBottom); } static void variable_item_list_draw_callback(Canvas* canvas, void* _model) { From d1e3b3cc9f3a305586f8b7289b6fbd5b6fa485b8 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Mon, 14 Oct 2024 17:39:38 +0800 Subject: [PATCH 11/20] format --- .../services/gui/modules/variable_item_list.c | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 34c9c77de9..1b660db3e7 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -82,7 +82,7 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { for(uint8_t i = start_option; i < end_option; i++) { uint8_t item_position = i - start_option; - + item->current_value_index = i; if(item->change_callback) { item->change_callback(item); @@ -99,22 +99,27 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { item->change_callback(item); } - //scroll bar - #define SCROLL_BAR_HEIGHT 0 +//scroll bar +#define SCROLL_BAR_HEIGHT 0 const uint8_t scroll_bar_y = canvas_height(canvas) - SCROLL_BAR_HEIGHT; - elements_scrollbar_horizontal(canvas, 0, scroll_bar_y, canvas_width(canvas), zapper_menu->current_page ,zapper_menu->total_pages); - - - //frame - #define GAP_SIZE_PX 1 - #define FRAME_HEIGHT 14 + elements_scrollbar_horizontal( + canvas, + 0, + scroll_bar_y, + canvas_width(canvas), + zapper_menu->current_page, + zapper_menu->total_pages); + +//frame +#define GAP_SIZE_PX 1 +#define FRAME_HEIGHT 14 for(int i = 0; i < 4; i++) { uint8_t y = i * (FRAME_HEIGHT + GAP_SIZE_PX); canvas_draw_rframe(canvas, 0, y, canvas_width(canvas), FRAME_HEIGHT, 3); } - //arrow - #define ARROR_SIZE 8 +//arrow +#define ARROR_SIZE 8 const uint8_t arrow_x = canvas_width(canvas) - 9; // ^ canvas_draw_triangle( From 6f14a91833cce94da9705a9022fd40a6897d4eda Mon Sep 17 00:00:00 2001 From: zxkmm Date: Mon, 14 Oct 2024 17:47:05 +0800 Subject: [PATCH 12/20] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fecfc23582..493212b7c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ - GUI: - OFW: Add up and down button drawing functions to GUI elements (by @DerSkythe) - OFW: Added one new function for drawing mirrored xbm bitmaps (by @RebornedBrain) + - Added a long press to quick select "Zapper" functionality for variable menu (#258 by @zxkmm) - OFW: RPC: Support 5V on GPIO control for ext. modules (by @gsurkov) - OFW: Toolbox: Proper integer parsing library `strint` (by @portasynthinca3) - OFW: Furi: Put errno into TCB (by @portasynthinca3) From f94d94849b6104a403353ef67a0ce7abe6c8d865 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Fri, 25 Oct 2024 16:13:47 +0800 Subject: [PATCH 13/20] fix changelog --- CHANGELOG.md | 64 ++++++++++++++++++++++++++++++++++++++++--- applications/external | 2 +- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2609d3280..3a7173dcc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,51 @@ - Reworks how communication with battery guage is done, improves reliability and fixes issues with battery percentage not showing - After installing firmware with this change, downgrading to old firmware will cause battery percentage to be blank - If you must downgrade firmware, use the [Guage Tool app](https://github.com/skotopes/flipperzero_gauge_tool) to unseal the guage +- OFW: JS: Modules backport & overhaul (by @portasynthinca3), backport of backport (by @Willy-JL & @xMasterX) + - OFW backported some modules we had, added lots of new stuff, and overhauled many other things + - Non-exhaustive list of changes to help you fix your scripts: + - `badusb`: + - `setup()`: `mfr_name`, `prod_name`, `layout_path` parameters renamed to `mfrName`, `prodName`, `layoutPath` + - effort required to update old scripts using badusb: very minimal + - `dialog`: + - removed, now replaced by `gui/dialog` and `gui/file_picker` (see below) + - `event_loop`: + - new module, allows timer functionality, callbacks and event-driven programming, used heavily alongside gpio and gui modules + - `gpio`: + - fully overhauled, now you `get()` pin instances and perform actions on them like `.init()` + - now supports interrupts, callbacks and more cool things + - effort required to update old scripts using gpio: moderate + - `gui`: + - new module, fully overhauled, replaces dialog, keyboard, submenu, textbox modules + - higher barrier to entry than older modules (requires usage of `event_loop` and `gui.viewDispatcher`), but much more flexible, powerful and easier to extend + - includes all previously available js gui functionality (except `widget`), and also adds `gui/loading` and `gui/empty_screen` views + - currently `gui/file_picker` works different than other new view objects, it is a simple `.pickFile()` synchronous function, but this [may change later](https://github.com/flipperdevices/flipperzero-firmware/pull/3961#discussion_r1805579153) + - effort required to update old scripts using gui: extensive + - `keyboard`: + - removed, now replaced by `gui/text_input` and `gui/byte_input` (see above) + - `math`: + - `is_equal()` renamed to `isEqual()` + - `storage`: + - fully overhauled, now you `openFile()`s and perform actions on them like `.read()` + - now supports many more operations including different open modes, directories and much more + - `virtualInit()`, `virtualMount()`, `virtualQuit()` still work the same + - effort required to update old scripts using storage: moderate + - `submenu`: + - removed, now replaced by `gui/submenu` (see above) + - `textbox`: + - removed, now replace by `gui/text_box` (see above) + - `widget`: + - only gui functionality not ported to new gui module, remains unchanged for now but likely to be ported later on + - globals: + - `__filepath` and `__dirpath` renamed to `__filename` and `__dirname` like in nodejs + - `to_string()` renamed and moved to number class as `n.toString()`, now supports optional base parameter + - `to_hex_string()` removed, now use `n.toString(16)` + - `parse_int()` renamed to `parseInt()`, now supports optional base parameter + - `to_upper_case()` and `to_lower_case()` renamed and moved to string class as `s.toUpperCase()` and `s.toLowerCase()` + - effort required to update old scripts using these: minimal + - Added type definitions (typescript files for type checking in IDE, Flipper does not run typescript) + - Documentation is incomplete and deprecated, from now on you should refer to type definitions (`applications/system/js_app/types`), those will always be correct + - Type definitions for extra modules we have that OFW doesn't will come later ### Added: - Apps: @@ -26,6 +71,8 @@ - Static encrypted backdoor support: collects static encrypted nonces to be cracked by MFKey using NXP/Fudan backdoor, allowing key recovery of all non-hardened MIFARE Classic tags on-device - Add SmartRider Parser (#203 by @jaylikesbunda) - Add API to enforce ISO15693 mode (#225 by @aaronjamt) + - OFW: H World Hotel Chain Room Key Parser and MFC keys (by @zinongli) + - OFW: Parser for Tianjin Railway Transit (by @zinongli) - Infrared: - Bluray/DVD Universal Remote (#250 #264 by @jaylikesbunda) - Option to "Load from Library File" for Universal Remotes (#255 by @zxkmm) @@ -38,9 +85,10 @@ - Add older qFlipper install demos for windows and macos (by @DXVVAY & @grugnoymeme) - OFW: New layout for es-LA (by @IRecabarren) - OFW: Dolphin: Happy mode in Desktop settings (by @portasynthinca3) +- OFW: CLI: Improvements part I, `neofetch` command (by @portasynthinca3), fix for lab.flipper.net (by @xMasterX) - GUI: - OFW: Add up and down button drawing functions to GUI elements (by @DerSkythe) - - OFW: Added one new function for drawing mirrored xbm bitmaps (by @RebornedBrain) + - OFW: Extended icon draw function in Canvas (by @RebornedBrain) - Added a long press to quick select "Zapper" functionality for variable menu (#258 by @zxkmm) - OFW: RPC: Support 5V on GPIO control for ext. modules (by @gsurkov) - OFW: Toolbox: Proper integer parsing library `strint` (by @portasynthinca3) @@ -57,7 +105,7 @@ - DTMF Dolphin: Add EAS tone support (by @JendrBendr) - NFC Playlist: Error screens for playlist already exists and item already in playlist, general improvements (by @acegoal07), refactor rename/new scene without thread (by @Willy-JL) - CLI-GUI Bridge: Fixes and improvements (by @ranchordo) - - Seader: Enable T=1 (by @bettse) + - Seader: Enable T=1, show error for timeout, fix wrong LRC logging, fix crash scanning NTAG215 with MFC option (by @bettse) - BLE Spam: Fix menu index callback (by @Willy-JL) - Solitaire: App rewrite, Added quick solve, New effects and sounds, Removed hacky canvas manipulation (by @doofy-dev) - CLI-GUI Bridge: Add more symbols to keyboard (#222 by @Willy-JL) @@ -65,6 +113,7 @@ - UL: NRF24 Apps: Use string library compatible with OFW SDK (by @xMasterX) - UL: W5500 Ethernet: Various fixes and improvements (by @xMasterX) - OFW: SPI Mem Manager: Fixed UI rendering bug related to line breaks (by @portasynthinca3) + - OFW: USB/BT Remote: Mouse clicker option to click as fast as possible (by @sumukhj1219) - CLI: Print plugin name on load fail (by @Willy-JL) - NFC: - NDEF Parser: @@ -73,7 +122,6 @@ - SmartPoster record support (#275 by @Willy-JL) - Enable parsing NTAG I2C Plus 1k and 2k chips too (#237 by @RocketGod-git) - Added 6 new Mifare Classic keys from Bulgaria Hotel (#216 by @z3r0l1nk) - - NDEF parser supports NTAG I2C Plus 1k and 2k chips too (by @RocketGod-git) - UL: Add iq aparts hotel key (by @xMasterX) - OFW/UL: Rename 'Detect Reader' to 'Extract MFC Keys' (by @bettse & @xMasterX) - OFW: Plantain parser improvements (by @assasinfil) @@ -95,6 +143,7 @@ - OFW: Add TCL 75S451 to TV universal remote (by @christhetech131) - OFW: Universal remote additions (by @jaylikesbunda) - OFW: Heavily Expand Universal Remotes (by @jaylikesbunda) +- OFW: BadKB: Improve ChromeOS and GNOME demo scripts (by @kowalski7cc) - OFW: GUI: Change dialog_ex text ownership model (by @skotopes) - OFW: CCID: App changes and improvements (by @kidbomb) - OFW: API: Exposed `view_dispatcher_get_event_loop` (by @CookiePLMonster) @@ -104,9 +153,11 @@ - OFW: Threading, Timers improvements (by @CookiePLMonster) - OFW: FuriTimer uses an event instead of a volatile bool to wait for deletion (by @CookiePLMonster) - OFW: Improve FuriThread state callbacks (by @CookiePLMonster) + - OFW: Increased heap size (by @hedger) - Documentation: - OFW: Update and cleanup (by @rnadyrshin) - OFW: Improve bit_buffer.h docs (by @Astrrra) + - OFW: Wi-Fi Devboard documentation rework (by @rnadyrshin) ### Fixed: - RFID: @@ -115,7 +166,9 @@ - OFW: GProxII Fix Writing and Rendering Conflict (by @zinongli) - Desktop: - Fallback Poweroff prompt when power settings is unavailable (by @Willy-JL) -- Sub-GHz: Fix GPS "Latitute" typo, switch to "Lat" and "Lon" in .sub files (#246 by @m7i-org) +- Sub-GHz: + - Fix GPS "Latitute" typo, switch to "Lat" and "Lon" in .sub files (#246 by @m7i-org) + - UL: Fix zero issues in Princeton (by @xMasterX) - Power: Suppress Shutdown on Idle While Charging / Plugged In (#244 by @luu176) - Storage: - Fallback SD format prompt when storage settings is unavailable (by @Willy-JL) @@ -123,6 +176,7 @@ - About: Fix BLE stack version string (by @Willy-JL) - OFW: Loader: Warn about missing SD card for main apps (by @Willy-JL) - NFC: + - UL: Read Ultralight block by block (by @mishamyte) - OFW: Fix crash on Ultralight unlock (by @Astrrra) - OFW: FeliCa anti-collision fix (by @RebornedBrain) - OFW: Emulation freeze fixed when pressing OK repeatedly (by @RebornedBrain) @@ -133,6 +187,8 @@ - OFW: Clean up of LFS traces (by @hedger) - OFW: Prevent idle priority threads from potentially starving the FreeRTOS idle task (by @CookiePLMonster) - OFW: Wait for RNG ready state and no errors before sampling (by @n1kolasM) + - OFW: A Lot of Fixes (by @skotopes) +- OFW: CLI: Add warning about stealth mode in vibro command (by @ivanbarsukov) - OFW: Debug: Use proper hook for handle_exit in flipperapps (by @skotopes) - OFW: API: Fix kerel typo in documentation (by @EntranceJew) diff --git a/applications/external b/applications/external index 067aa52f52..36671ed586 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 067aa52f521e3f05e2181f753bffab733c424602 +Subproject commit 36671ed586d0d47d9a95f07d6775986117c2b7df From f28862aa7bdce273522814919fa73c7413db7f81 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Fri, 25 Oct 2024 16:18:19 +0800 Subject: [PATCH 14/20] fix submodule mistaken checkout --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index 36671ed586..067aa52f52 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 36671ed586d0d47d9a95f07d6775986117c2b7df +Subproject commit 067aa52f521e3f05e2181f753bffab733c424602 From 7d13ba18d0dad8978e900575750fb3d6cfe26705 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Wed, 13 Nov 2024 19:11:19 +0800 Subject: [PATCH 15/20] only draw frame and arror when has the exact item --- applications/services/gui/modules/variable_item_list.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 1b660db3e7..27cebbd13f 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -110,10 +110,11 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { zapper_menu->current_page, zapper_menu->total_pages); + const uint8_t draw_count = end_option - start_option; //frame #define GAP_SIZE_PX 1 #define FRAME_HEIGHT 14 - for(int i = 0; i < 4; i++) { + for(int i = 0; i < draw_count; i++) { uint8_t y = i * (FRAME_HEIGHT + GAP_SIZE_PX); canvas_draw_rframe(canvas, 0, y, canvas_width(canvas), FRAME_HEIGHT, 3); } @@ -124,12 +125,15 @@ static void zapper_menu_draw(Canvas* canvas, VariableItemListModel* model) { // ^ canvas_draw_triangle( canvas, arrow_x, 16 - (16 - 9) / 2 - 3, ARROR_SIZE, ARROR_SIZE, CanvasDirectionBottomToTop); + if(draw_count == 1) return; // < canvas_draw_triangle( canvas, arrow_x + 9 / 2, 24 - 2, ARROR_SIZE, ARROR_SIZE, CanvasDirectionRightToLeft); + if(draw_count == 2) return; // > canvas_draw_triangle( canvas, arrow_x - 9 / 2 + 2, 40 - 4, ARROR_SIZE, ARROR_SIZE, CanvasDirectionLeftToRight); + if(draw_count == 3) return; // v canvas_draw_triangle( canvas, arrow_x, 16 * 3 + 6 - 6, ARROR_SIZE, ARROR_SIZE, CanvasDirectionTopToBottom); From 983a9469ef6bcca5e5df56a52c00718862a77dc2 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 7 Dec 2024 19:15:49 +0800 Subject: [PATCH 16/20] (dummy commit to make github show diff view correctly after merge upstream on github webpage) --- CHANGELOG.md | 2 ++ applications/external | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15ca71c083..081c0dd934 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -246,3 +246,5 @@ - ESP Flasher: - Removed Airtag Scanner and ESP32-S2 Wardriver due to low user interest and to make space for Ghost ESP - API: Removed `furi_hal_bt_reverse_mac_addr()` and implemented in individual apps instead + +(dummy commit to make github show diff view correctly after merge upstream on github webpage) diff --git a/applications/external b/applications/external index 1163b58398..861fe33513 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 1163b5839883072526c029f9f636507b7f318f14 +Subproject commit 861fe3351399f62a705bf3ebea3ca291b4319670 From 63c50756c65c51b9ef114d799e28c9f34bcd48e0 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 7 Dec 2024 19:16:57 +0800 Subject: [PATCH 17/20] (dummy commit to make github show diff view correctly after merge upstream on github webpage) --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 081c0dd934..15ca71c083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -246,5 +246,3 @@ - ESP Flasher: - Removed Airtag Scanner and ESP32-S2 Wardriver due to low user interest and to make space for Ghost ESP - API: Removed `furi_hal_bt_reverse_mac_addr()` and implemented in individual apps instead - -(dummy commit to make github show diff view correctly after merge upstream on github webpage) From b9414bb5a7abbed69b03e62f2309b1c50aceab72 Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sat, 7 Dec 2024 19:18:07 +0800 Subject: [PATCH 18/20] submodule --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index 861fe33513..1163b58398 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 861fe3351399f62a705bf3ebea3ca291b4319670 +Subproject commit 1163b5839883072526c029f9f636507b7f318f14 From 9fc457ee1c2b0e7242a2076957b5323a27c62dfd Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sun, 8 Dec 2024 11:56:43 +0800 Subject: [PATCH 19/20] remove changelog --- CHANGELOG.md | 267 ++++++--------------------------------------------- 1 file changed, 28 insertions(+), 239 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15ca71c083..5d478ac699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,248 +1,37 @@ -### Breaking Changes: -- OFW: Battery: Rework gauge driver initialization routine (by @skotopes) - - Reworks how communication with battery guage is done, improves reliability and fixes issues with battery percentage not showing - - After installing firmware with this change, downgrading to old firmware will cause battery percentage to be blank - - If you must downgrade firmware, use the [Guage Tool app](https://github.com/skotopes/flipperzero_gauge_tool) to unseal the guage -- OFW: Furi: RTC Alarm support (目覚め時計) (by @skotopes) - - Reworks RTC initialization to support Alarms functionality - - Older firmware will be unable to handle alarm, downgrading might be problematic - - If you must downgrade firmware, disable Alarm in Settings > Clock & Alarm first -- OFW: JS: Modules backport & overhaul (by @portasynthinca3), backport of backport (by @Willy-JL & @xMasterX) - - OFW backported some modules we had, added lots of new stuff, and overhauled many other things - - Non-exhaustive list of changes to help you fix your scripts: - - `badusb`: - - `setup()`: `mfr_name`, `prod_name`, `layout_path` parameters renamed to `mfrName`, `prodName`, `layoutPath` - - effort required to update old scripts using badusb: very minimal - - `dialog`: - - removed, now replaced by `gui/dialog` and `gui/file_picker` (see below) - - `event_loop`: - - new module, allows timer functionality, callbacks and event-driven programming, used heavily alongside gpio and gui modules - - `gpio`: - - fully overhauled, now you `get()` pin instances and perform actions on them like `.init()` - - now supports interrupts, callbacks and more cool things - - effort required to update old scripts using gpio: moderate - - `gui`: - - new module, fully overhauled, replaces dialog, keyboard, submenu, textbox modules - - higher barrier to entry than older modules (requires usage of `event_loop` and `gui.viewDispatcher`), but much more flexible, powerful and easier to extend - - includes all previously available js gui functionality (except `widget`), and also adds `gui/loading` and `gui/empty_screen` views - - currently `gui/file_picker` works different than other new view objects, it is a simple `.pickFile()` synchronous function, but this [may change later](https://github.com/flipperdevices/flipperzero-firmware/pull/3961#discussion_r1805579153) - - effort required to update old scripts using gui: extensive - - `keyboard`: - - removed, now replaced by `gui/text_input` and `gui/byte_input` (see above) - - `math`: - - `is_equal()` renamed to `isEqual()` - - `storage`: - - fully overhauled, now you `openFile()`s and perform actions on them like `.read()` - - now supports many more operations including different open modes, directories and much more - - `virtualInit()`, `virtualMount()`, `virtualQuit()` still work the same - - effort required to update old scripts using storage: moderate - - `submenu`: - - removed, now replaced by `gui/submenu` (see above) - - `textbox`: - - removed, now replace by `gui/text_box` (see above) - - `widget`: - - only gui functionality not ported to new gui module, remains unchanged for now but likely to be ported later on - - globals: - - `__filepath` and `__dirpath` renamed to `__filename` and `__dirname` like in nodejs - - `to_string()` renamed and moved to number class as `n.toString()`, now supports optional base parameter - - `to_hex_string()` removed, now use `n.toString(16)` - - `parse_int()` renamed to `parseInt()`, now supports optional base parameter - - `to_upper_case()` and `to_lower_case()` renamed and moved to string class as `s.toUpperCase()` and `s.toLowerCase()` - - effort required to update old scripts using these: minimal - - Added type definitions (typescript files for type checking in IDE, Flipper does not run typescript) - - Documentation is incomplete and deprecated, from now on you should refer to type definitions (`applications/system/js_app/packages/fz-sdk`), those will always be correct -- GUI: Refactored TextInput illegal symbols (by @Willy-JL) - - If your app used `text_input_add_illegal_symbols(text_input)` it should change to `text_input_show_illegal_symbols(text_input, true)` - ### Added: + - Apps: - - NFC: Cyborg Detector (by @RocketGod-git) - - Sub-GHz: Radio Scanner (by @RocketGod-git) - - GPIO: FlipperHTTP app suite (by @jblanked): - - FlipLibrary - - FlipSocial - - FlipStore - - FlipTrader - - FlipWeather - - FlipWiFi - - Web Crawler - - Tools: uPython (by @ofabel) - - Games: Umpire Indicator (by @RocketGod-git) -- Sub-GHz: - - Show satellites count with an icon (#215 by @m7i-org) - - Add Bresser 3CH weather station protocol (#217 #245 by @m7i-org) - - Add Vauno-EN8822 weather station protocol (#262 by @m7i-org) - - UL: Add Marantec24 protocol (static 24 bit) with add manually (by @xMasterX) - - UL: Add GangQi protocol (static 34 bit) with button parsing and add manually (by @xMasterX & @Skorpionm) - - UL: Add Hollarm protocol (static 42 bit) with button parsing and add manually (by @xMasterX & @Skorpionm) - - UL: Add Hay21 protocol (dynamic 21 bit) with button parsing (by @xMasterX) - - UL: Add Keeloq Monarch full support, with add manually (by @ashphx & @xMasterX) - - UL: Princeton custom buttons support (by @xMasterX) -- NFC: - - OFW: MIFARE Classic Key Recovery Improvements (PR 3822 by @noproto) - - Accelerated dictionary attack: dictionary attacks reduced to several seconds - checks ~3500 keys per second - - Nested attack support: collects nested nonces to be cracked by MFKey, no longer requiring Flipper Nested app - - Static encrypted backdoor support: collects static encrypted nonces to be cracked by MFKey using NXP/Fudan backdoor, allowing key recovery of all non-hardened MIFARE Classic tags on-device - - Add SmartRider Parser (#203 by @jaylikesbunda) - - Add API to enforce ISO15693 mode (#225 by @aaronjamt) - - OFW: H World Hotel Chain Room Key Parser and MFC keys (by @zinongli) - - OFW: Parser for Tianjin Railway Transit (by @zinongli) -- Infrared: - - Bluray/DVD Universal Remote (#250 #264 by @jaylikesbunda) - - Option to "Load from Library File" for Universal Remotes (#255 by @zxkmm) -- Updater: New Yappy themed icon while updating (#253 by @the1anonlypr3 & @Kuronons & @nescap) -- JS: - - OFW: JS: Modules backport & overhaul (by @portasynthinca3) - - See above for list of breaking changes, here are listed strictly new functionalities - - New `event_loop` module for event-driven interactivity - - Interrupt and callback support for `gpio` module - - New `gui` module that allows much more developed interfaces, also new `gui/loading` and `gui/empty_screen` views - - Directory operations and many more file operations for `storage` module - - OFW: Full-fledged JS SDK + npm packages (by @portasynthinca3) - - CFWs can have their own JS SDKs too! Check ours out at [`@next-flip/fz-sdk-mntm`](https://www.npmjs.com/package/@next-flip/fz-sdk-mntm) - - New `i2c` module (#259 by @jamisonderek) - - New `spi` module (#272 by @jamisonderek) - - Added `illegalSymbols` prop for `gui/text_input` view (#290 by @Willy-JL) - - Added typedocs for all extra JS modules in Momentum (by @Willy-JL) -- RPC: Added ASCII event support (#284 by @Willy-JL) -- FBT/SDK: New app flag UnloadAssetPacks to free RAM in heavy apps like NFC, MFKey, uPython (#260 by @Willy-JL) -- Settings: - - OFW: Clock editing & Alarm function (目覚め時計) (by @skotopes) - - Add warnings for some settings you shouldn't touch like Debug, Sleep Method, Heap Trace (#296 by @Willy-JL) -- BadKB: - - OFW: Add linux/gnome badusb demo files (by @thomasnemer) - - Add older qFlipper install demos for windows and macos (by @DXVVAY & @grugnoymeme) - - OFW: New layout for es-LA (by @IRecabarren) -- OFW: Dolphin: Happy mode in Desktop settings (by @portasynthinca3) -- OFW: CLI: Improvements part I, `neofetch` command (by @portasynthinca3), fix for lab.flipper.net (by @xMasterX) -- GUI: - - ByteInput supports ASCII input (by @Willy-JL) - - OFW: Add up and down button drawing functions to GUI elements (by @DerSkythe) - - OFW: Extended icon draw function in Canvas (by @RebornedBrain) - - Added a long press to quick select "Zapper" functionality for variable menu (#258 by @zxkmm) -- OFW: RPC: Support 5V on GPIO control for ext. modules (by @gsurkov) -- OFW: Toolbox: Proper integer parsing library `strint` (by @portasynthinca3) -- Furi: - - OFW: Add FuriEventLoop support for FuriEventFlag, simplify API (by @Skorpionm) - - OFW: Put errno into TCB, better integration with libc (by @portasynthinca3) + - Games: Pinball0 (by @rdefeo) + - NFC: Metroflip (by @luu176) ### Updated: + - Apps: - - MFKey: Added Static Encrypted Nested key recovery, Added NFC app support, Dropped FlipperNested support (by @noproto) - - WAV Player: Better fix for unresponsiveness, handle thread exit signal (by @CookiePLMonster) - - Laser Tag: External Infrared board support, crash fixes (by @RocketGod-git), RFID support for ammo reload, thread leak fix (by @jamisonderek) - - ESP Flasher: Add FlipperHTTP firmware (by @jblanked), update blackmagic bin with WiFi Logs (by @DrZlo13), support more board types (by @xMasterX) - - Picopass: File loading improvements and fixes (by @bettse), force ISO15693 1OutOf4 mode (by @aaronjamt) - - Quac!: External IR board support (by @daniilty), import all IR from file, iButton support, code improvements (by @rdefeo) - - DTMF Dolphin: Add EAS tone support (by @JendrBendr) - - NFC Playlist: Better error handling with many new error screens, general improvements (by @acegoal07), refactor rename/new scene without thread (by @Willy-JL) - - CLI-GUI Bridge: Fixes and improvements (by @ranchordo) - - Seader: Enable T=1, show error for timeout, fix wrong LRC logging, fix crash scanning NTAG215 with MFC option (by @bettse) - - BLE Spam: Fix menu index callback (by @Willy-JL) - - Solitaire: App rewrite, Added quick solve, New effects and sounds, Removed hacky canvas manipulation (by @doofy-dev) - - Flappy Bird: Yappy Bird and Yappy Ghost characters, highscore system and bugfixes (by @jaylikesbunda & @the1anonlypr3) - - CLI-GUI Bridge: Add more symbols to keyboard (#222 by @Willy-JL) - - NRF24 Batch: Add Aeropac SN board txt file (by @vad7) - - UL: Sub-GHz Bruteforcer: Add new protocols for existing dump option (by @xMasterX), use FW functions for top buttons (by @DerSkythe) - - UL: RFID/iButton Fuzzer: Add protocols Electra, Idteck, Gallagher, Nexwatch, refactor to make RFID protocols easier to add (by @SkeletonMan03), add more Dallas 1990 IDs (by @eblis) - - UL: NRF24 Apps: Use string library compatible with OFW SDK (by @xMasterX) - - UL: W5500 Ethernet: Various fixes and improvements (by @xMasterX) - - OFW: SPI Mem Manager: Fixed UI rendering bug related to line breaks (by @portasynthinca3) - - OFW: USB/BT Remote: Mouse clicker option to click as fast as possible (by @sumukhj1219) -- NFC: - - NDEF Parser: - - Mifare Classic support (#265 by @luu176), protocol-agnostic rewrite and more improvements (#265 by @Willy-JL) - - SLIX support, parse even with TLV terminator omitted, parse empty NDEF TLVs (#278 by @Willy-JL) - - Decoding of URL-encoded URI characters (#267 by @jaylikesbunda) - - SmartPoster record support (#275 by @Willy-JL) - - Enable parsing NTAG I2C Plus 1k and 2k chips too (#237 by @RocketGod-git) - - NFC: Updated MFC dict, +100 keys from RRG proxmark3, +17 keys from Mifare Classic Tool - - Added 6 new Mifare Classic keys from Bulgaria Hotel (#216 by @z3r0l1nk) - - UL: Add iq aparts hotel key (by @xMasterX) - - OFW/UL: Rename 'Detect Reader' to 'Extract MFC Keys' (by @bettse & @xMasterX) - - OFW: Plantain parser improvements (by @assasinfil) and fixes (by @mxcdoam) - - OFW: Moscow social card parser (by @assasinfil) - - OFW: Fixes and improvements to iso14443_4a listener and poller (by @RebornedBrain) - - OFW: Update BART station codes in Clipper plugin (by @ted-logan) - - OFW: Add Caltrain zones for Clipper parser (by @tomholford) -- Sub-GHz: - - UL: Frequency analyzer fixes and improvements (by @xMasterX): - - Enforce int module (like in OFW) usage due to lack of required hardware on external boards (PathIsolate (+rf switch for multiple paths)) and incorrect usage and/or understanding the purpose of frequency analyzer app by users, it should be used only to get frequency of the remote placed around 1-10cm around flipper's left corner - - Fix possible GSM mobile towers signal interference by limiting upper frequency to 920mhz max - - Fix duplicated frequency lists and use user config for nearest frequency selector too - - Nexus-TH weather station protocol improvements on detection (#256 by @m7i-org) -- Infrared: - - Additions to MNTM specific LED, Digital Sign, Monitor universal remotes from IRDB (#240 by @jaylikesbunda) - - UL: Replace LEDs universal remote with new one by Unleashed team, includes color options (by @amec0e & @xMasterX) - - UL: Update universal remote assets (by @amec0e) - - OFW: IR button operation fails now shows more informative messages (by @RebornedBrain) - - OFW: Add Airwell AW-HKD012-N91 to univeral AC remote (by @valeraOlexienko) - - OFW: Add TCL 75S451 to TV universal remote (by @christhetech131) - - OFW: Universal remote additions (by @jaylikesbunda) - - OFW: Heavily Expand Universal Remotes (by @jaylikesbunda) -- CLI: - - Print plugin name on load fail (by @Willy-JL) - - Move more commands as plugins on SD, refactor plugin wrapper (#276 by @Willy-JL) -- FBT: Optimize icons blob, scrub unused icons (#291 by @Willy-JL) -- OFW: BadKB: Improve ChromeOS and GNOME demo scripts (by @kowalski7cc) -- GUI: - - OFW: Change dialog_ex text ownership model (by @skotopes) - - Improve some error messages to be more clear, like Sub-GHz region missing and Main Menu .fap file missing (#296 by @Willy-JL) -- OFW: CCID: App changes and improvements (by @kidbomb) -- OFW: API: Exposed `view_dispatcher_get_event_loop` (by @CookiePLMonster) -- Furi: - - UL: Extra checks for OTG power enable/disable (by @xMasterX) - - OFW: Replace all calls to strncpy with strlcpy, use strdup more, expose strlcat (by @CookiePLMonster) - - OFW: Threading, Timers improvements (by @CookiePLMonster) - - OFW: FuriTimer uses an event instead of a volatile bool to wait for deletion (by @CookiePLMonster) - - OFW: Improve FuriThread state callbacks (by @CookiePLMonster) - - OFW: Increased heap size (by @hedger) -- Documentation: - - OFW: Update and cleanup (by @rnadyrshin) - - OFW: Improve bit_buffer.h docs (by @Astrrra) - - OFW: Wi-Fi Devboard documentation rework (by @rnadyrshin) - - OFW: Update unit tests docs (by @portasynthinca3) + - BT/USB Remote: Add PTT support for Gather (by @SapphicCode) + - ESP Flasher: Add c3 and c6 to s3 option (by @jaylikesbunda) + - FlipLibrary: Added Wikipedia, dog facts and random quotes, bug fixes (by @jblanked), connectivity and progress + improvements (by @jamisonderek) + - FlipSocial: Improved authentication (by @jblanked) + - FlipStore: Many bugfixes, support ESP32 firmware downloads, allow deleting apps (by @jblanked) + - FlipTrader: Improved progress display, added connectivity check on startup (by @jamisonderek) + - FlipWeather: Stability improvements (by @jblanked), improved progress display, added connectivity check on + startup (by @jamisonderek) + - FlipWiFi: Improved error handling, updated scan loading and parsing (by @jblanked), added connectivity check on + startup (by @jamisonderek) + - FlipBIP: Refactor to make adding coins easier (by @xtruan) + - uPython: Enabled extra functions for the `random` module (by @ofabel) + - Pokemon Trade Tool: Update to gblink v0.63 which includes saving/loading of pin configurations for the EXT link + interface (by @kbembedded) + - Snake 2.0: Progress saving, endless mode, game timer, fruit positioning bugfixes (by @Willzvul) + - WebCrawler: Improved progress display, added connectivity check on startup (by @jamisonderek) + - UL: NFC Magic: Added possibility to write 7b MFC to Gen1 tags (by @mishamyte) + - UL: Fixed apps for firmware USB CDC callback changes (by @xMasterX) ### Fixed: -- RFID: - - OFW: Fix detection of GProx II cards and false detection of other cards (by @Astrrra) - - OFW: Fix Guard GProxII False Positive and 36-bit Parsing (by @zinongli) - - OFW: GProxII Fix Writing and Rendering Conflict (by @zinongli) -- Asset Packer: Fix font terminator causing freezes/crashes, like in Marauder AP scan/list (#295 by @Willy-JL) -- Desktop: - - Fallback Poweroff prompt when power settings is unavailable (by @Willy-JL) -- Sub-GHz: - - Fix GPS "Latitute" typo, switch to "Lat" and "Lon" in .sub files (#246 by @m7i-org) - - UL: Fix zero issues in Princeton (by @xMasterX) - - UL: Code cleanup and fix for rare dupicated "Data" field cases (by @xMasterX) - - UL: Fix Nice One key display (by @xMasterX) -- Power: Suppress Shutdown on Idle While Charging / Plugged In (#244 by @luu176) -- Storage: - - Fallback SD format prompt when storage settings is unavailable (by @Willy-JL) - - OFW: Fix folder rename fails (by @portasynthinca3) -- About: Fix BLE stack version string (by @Willy-JL) -- RPC: Fixed apps not updating and staying at 100% (by @Willy-JL) -- OFW: Loader: Warn about missing SD card for main apps (by @Willy-JL) -- NFC: - - OFW: Fix crash on Ultralight unlock (by @Astrrra) - - OFW: FeliCa anti-collision fix (by @RebornedBrain) - - OFW: Emulation freeze fixed when pressing OK repeatedly (by @RebornedBrain) - - OFW: Fixed bug with reading pwd locked MFULs (by @mishamyte) -- OFW: RPC: Broken file interaction fixes (by @RebornedBrain) -- OFW: GPIO: Fix USB-UART bridge exit screen stopping the bridge prematurely (by @portasynthinca3) -- OFW: GUI: Fix dialog_ex NULL ptr crash (by @Willy-JL) -- Furi: - - OFW: Clean up of LFS traces (by @hedger) - - OFW: Prevent idle priority threads from potentially starving the FreeRTOS idle task (by @CookiePLMonster) - - OFW: Wait for RNG ready state and no errors before sampling (by @n1kolasM) - - OFW: A Lot of Fixes (by @skotopes) -- OFW: CLI: Add warning about stealth mode in vibro command (by @ivanbarsukov) -- OFW: Debug: Use proper hook for handle_exit in flipperapps (by @skotopes) -- OFW: API: Fix kerel typo in documentation (by @EntranceJew) + +- Desktop: Fixed Wardriving animation design (by @Davim09) +- OFW: GPIO: Merged gsurkov/vcp_break_support branch for usb uart bridge (WIP!!!) ### Removed: -- Apps: - - Mifare Nested: Superseded by NFC app after OFW PR 3822 (MIFARE Classic Key Recovery Improvements) - - ESP Flasher: - - Removed Airtag Scanner and ESP32-S2 Wardriver due to low user interest and to make space for Ghost ESP -- API: Removed `furi_hal_bt_reverse_mac_addr()` and implemented in individual apps instead + +- Nothing \ No newline at end of file From 752f5b7ceabdee1bb4f0be2d5cd6c75e51921b1e Mon Sep 17 00:00:00 2001 From: zxkmm Date: Sun, 8 Dec 2024 12:06:40 +0800 Subject: [PATCH 20/20] remove changelog --- CHANGELOG.md | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d478ac699..9d6760bb64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,37 +1,29 @@ ### Added: - - Apps: - - Games: Pinball0 (by @rdefeo) - - NFC: Metroflip (by @luu176) + - Games: Pinball0 (by @rdefeo) + - NFC: Metroflip (by @luu176) ### Updated: - - Apps: - - BT/USB Remote: Add PTT support for Gather (by @SapphicCode) - - ESP Flasher: Add c3 and c6 to s3 option (by @jaylikesbunda) - - FlipLibrary: Added Wikipedia, dog facts and random quotes, bug fixes (by @jblanked), connectivity and progress - improvements (by @jamisonderek) - - FlipSocial: Improved authentication (by @jblanked) - - FlipStore: Many bugfixes, support ESP32 firmware downloads, allow deleting apps (by @jblanked) - - FlipTrader: Improved progress display, added connectivity check on startup (by @jamisonderek) - - FlipWeather: Stability improvements (by @jblanked), improved progress display, added connectivity check on - startup (by @jamisonderek) - - FlipWiFi: Improved error handling, updated scan loading and parsing (by @jblanked), added connectivity check on - startup (by @jamisonderek) - - FlipBIP: Refactor to make adding coins easier (by @xtruan) - - uPython: Enabled extra functions for the `random` module (by @ofabel) - - Pokemon Trade Tool: Update to gblink v0.63 which includes saving/loading of pin configurations for the EXT link - interface (by @kbembedded) - - Snake 2.0: Progress saving, endless mode, game timer, fruit positioning bugfixes (by @Willzvul) - - WebCrawler: Improved progress display, added connectivity check on startup (by @jamisonderek) - - UL: NFC Magic: Added possibility to write 7b MFC to Gen1 tags (by @mishamyte) - - UL: Fixed apps for firmware USB CDC callback changes (by @xMasterX) + - BT/USB Remote: Add PTT support for Gather (by @SapphicCode) + - ESP Flasher: Add c3 and c6 to s3 option (by @jaylikesbunda) + - FlipLibrary: Added Wikipedia, dog facts and random quotes, bug fixes (by @jblanked), connectivity and progress improvements (by @jamisonderek) + - FlipSocial: Improved authentication (by @jblanked) + - FlipStore: Many bugfixes, support ESP32 firmware downloads, allow deleting apps (by @jblanked) + - FlipTrader: Improved progress display, added connectivity check on startup (by @jamisonderek) + - FlipWeather: Stability improvements (by @jblanked), improved progress display, added connectivity check on startup (by @jamisonderek) + - FlipWiFi: Improved error handling, updated scan loading and parsing (by @jblanked), added connectivity check on startup (by @jamisonderek) + - FlipBIP: Refactor to make adding coins easier (by @xtruan) + - uPython: Enabled extra functions for the `random` module (by @ofabel) + - Pokemon Trade Tool: Update to gblink v0.63 which includes saving/loading of pin configurations for the EXT link interface (by @kbembedded) + - Snake 2.0: Progress saving, endless mode, game timer, fruit positioning bugfixes (by @Willzvul) + - WebCrawler: Improved progress display, added connectivity check on startup (by @jamisonderek) + - UL: NFC Magic: Added possibility to write 7b MFC to Gen1 tags (by @mishamyte) + - UL: Fixed apps for firmware USB CDC callback changes (by @xMasterX) ### Fixed: - - Desktop: Fixed Wardriving animation design (by @Davim09) - OFW: GPIO: Merged gsurkov/vcp_break_support branch for usb uart bridge (WIP!!!) ### Removed: - - Nothing \ No newline at end of file