diff --git a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c index eb6911df74..c2aaac5bee 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c +++ b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c @@ -169,7 +169,7 @@ static void nfc_scene_read_setup_view(NfcApp* instance) { popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50); popup_set_header(instance->popup, "Unlocking", 97, 15, AlignCenter, AlignTop); popup_set_text( - instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop); + instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop); } else { popup_set_header(instance->popup, "Don't move", 85, 27, AlignCenter, AlignTop); popup_set_icon(instance->popup, 12, 20, &A_Loading_24); diff --git a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight_render.c b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight_render.c index 1bc508adce..c4ad67ff8b 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight_render.c +++ b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight_render.c @@ -11,7 +11,11 @@ static void nfc_render_mf_ultralight_pages_count(const MfUltralightData* data, F void nfc_render_mf_ultralight_pwd_pack(const MfUltralightData* data, FuriString* str) { bool all_pages = mf_ultralight_is_all_data_read(data); - furi_string_cat_printf(str, "\e#%s pages unlocked!", all_pages ? "All" : "Not all"); + if(all_pages) { + furi_string_cat_printf(str, "\e#All Pages Are Unlocked!"); + } else { + furi_string_cat_printf(str, "\e#Some Pages Are Locked!"); + } MfUltralightConfigPages* config; mf_ultralight_get_config_page(data, &config); diff --git a/applications/main/nfc/plugins/supported_cards/myki.c b/applications/main/nfc/plugins/supported_cards/myki.c index 4da5d30afb..b023a913ab 100644 --- a/applications/main/nfc/plugins/supported_cards/myki.c +++ b/applications/main/nfc/plugins/supported_cards/myki.c @@ -73,7 +73,7 @@ static bool myki_parse(const NfcDevice* device, FuriString* parsed_data) { // Stored card number doesn't include check digit card_number += myki_calculate_luhn(card_number); - furi_string_set(parsed_data, "\e#myki\n"); + furi_string_set(parsed_data, "\e#myki\nNo.: "); // Stylise card number according to the physical card char card_string[20]; diff --git a/applications/main/nfc/plugins/supported_cards/opal.c b/applications/main/nfc/plugins/supported_cards/opal.c index d83e908f1d..60db7ed1ee 100644 --- a/applications/main/nfc/plugins/supported_cards/opal.c +++ b/applications/main/nfc/plugins/supported_cards/opal.c @@ -170,7 +170,7 @@ static bool opal_parse(const NfcDevice* device, FuriString* parsed_data) { furi_string_printf( parsed_data, - "\e#Opal: $%s%ld.%02hu\n3085 22%02hhu %04hu %03hu%01hhu\n%s, %s\n", + "\e#Opal: $%s%ld.%02hu\nNo.: 3085 22%02hhu %04hu %03hu%01hhu\n%s, %s\n", sign, balance_dollars, balance_cents, diff --git a/applications/main/nfc/plugins/supported_cards/plantain.c b/applications/main/nfc/plugins/supported_cards/plantain.c index ebdc902e84..bba31b5592 100644 --- a/applications/main/nfc/plugins/supported_cards/plantain.c +++ b/applications/main/nfc/plugins/supported_cards/plantain.c @@ -191,7 +191,7 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) { } furi_string_printf( - parsed_data, "\e#Plantain\nN:%llu-\nBalance:%lu\n", card_number, balance); + parsed_data, "\e#Plantain\nNo.: %llu?\nBalance:%lu\n", card_number, balance); parsed = true; } while(false); diff --git a/applications/main/nfc/plugins/supported_cards/two_cities.c b/applications/main/nfc/plugins/supported_cards/two_cities.c index fc7d2d0261..bffdcb2c2d 100644 --- a/applications/main/nfc/plugins/supported_cards/two_cities.c +++ b/applications/main/nfc/plugins/supported_cards/two_cities.c @@ -157,7 +157,7 @@ static bool two_cities_parse(const NfcDevice* device, FuriString* parsed_data) { furi_string_printf( parsed_data, - "\e#Troika+Plantain\nPN: %llu-\nPB: %lu rur.\nTN: %lu\nTB: %u rur.\n", + "\e#Troika+Plantain\nPN: %llu?\nPB: %lu rur.\nTN: %lu\nTB: %u rur.\n", card_number, balance, troika_number, diff --git a/applications/main/nfc/scenes/nfc_scene_config.h b/applications/main/nfc/scenes/nfc_scene_config.h index 94d845fa36..e522cd059a 100644 --- a/applications/main/nfc/scenes/nfc_scene_config.h +++ b/applications/main/nfc/scenes/nfc_scene_config.h @@ -45,10 +45,11 @@ ADD_SCENE(nfc, mf_classic_mfkey_nonces_info, MfClassicMfkeyNoncesInfo) ADD_SCENE(nfc, mf_classic_mfkey_complete, MfClassicMfkeyComplete) ADD_SCENE(nfc, mf_classic_update_initial, MfClassicUpdateInitial) ADD_SCENE(nfc, mf_classic_update_initial_success, MfClassicUpdateInitialSuccess) +ADD_SCENE(nfc, mf_classic_update_initial_wrong_card, MfClassicUpdateInitialWrongCard) ADD_SCENE(nfc, mf_classic_write_initial, MfClassicWriteInitial) ADD_SCENE(nfc, mf_classic_write_initial_success, MfClassicWriteInitialSuccess) ADD_SCENE(nfc, mf_classic_write_initial_fail, MfClassicWriteInitialFail) -ADD_SCENE(nfc, mf_classic_wrong_card, MfClassicWrongCard) +ADD_SCENE(nfc, mf_classic_write_initial_wrong_card, MfClassicWriteInitialWrongCard) ADD_SCENE(nfc, mf_classic_keys, MfClassicKeys) ADD_SCENE(nfc, mf_classic_keys_list, MfClassicKeysList) diff --git a/applications/main/nfc/scenes/nfc_scene_detect.c b/applications/main/nfc/scenes/nfc_scene_detect.c index 34c552aba5..3ef153657d 100644 --- a/applications/main/nfc/scenes/nfc_scene_detect.c +++ b/applications/main/nfc/scenes/nfc_scene_detect.c @@ -19,7 +19,7 @@ void nfc_scene_detect_on_enter(void* context) { popup_reset(instance->popup); popup_set_header(instance->popup, "Reading", 97, 15, AlignCenter, AlignTop); popup_set_text( - instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop); + instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop); popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50); view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_warn_duplicate.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_warn_duplicate.c index c3fb92bee0..675463ec96 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_warn_duplicate.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_keys_warn_duplicate.c @@ -12,7 +12,7 @@ void nfc_scene_mf_classic_keys_warn_duplicate_on_enter(void* context) { // Setup view Popup* popup = instance->popup; popup_set_icon(popup, 83, 22, &I_WarningDolphinFlip_45x42); - popup_set_header(popup, "Key already exists!", 64, 3, AlignCenter, AlignTop); + popup_set_header(popup, "Key Already Exists!", 64, 3, AlignCenter, AlignTop); popup_set_text( popup, "Please enter a\n" diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_mfkey_complete.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_mfkey_complete.c index eb0aa7c3ae..d5033789a1 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_mfkey_complete.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_mfkey_complete.c @@ -14,7 +14,7 @@ void nfc_scene_mf_classic_mfkey_complete_on_enter(void* context) { NfcApp* instance = context; widget_add_string_element( - instance->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Complete!"); + instance->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Completed!"); widget_add_string_multiline_element( instance->widget, 64, diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_initial.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_initial.c index 961afdf531..7c76260b4f 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_initial.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_initial.c @@ -61,7 +61,7 @@ static void nfc_scene_mf_classic_update_initial_setup_view(NfcApp* instance) { if(state == NfcSceneMfClassicUpdateInitialStateCardSearch) { popup_set_text( - instance->popup, "Apply the initial\ncard only", 128, 32, AlignRight, AlignCenter); + instance->popup, "Use the source\ncard only", 128, 32, AlignRight, AlignCenter); popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50); } else { popup_set_header(popup, "Updating\nDon't move...", 52, 32, AlignLeft, AlignCenter); @@ -111,14 +111,16 @@ bool nfc_scene_mf_classic_update_initial_on_event(void* context, SceneManagerEve nfc_scene_mf_classic_update_initial_setup_view(instance); consumed = true; } else if(event.event == NfcCustomEventWrongCard) { - scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWrongCard); + scene_manager_next_scene( + instance->scene_manager, NfcSceneMfClassicUpdateInitialWrongCard); consumed = true; } else if(event.event == NfcCustomEventWorkerExit) { if(nfc_save_shadow_file(instance)) { scene_manager_next_scene( instance->scene_manager, NfcSceneMfClassicUpdateInitialSuccess); } else { - scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWrongCard); + scene_manager_next_scene( + instance->scene_manager, NfcSceneMfClassicUpdateInitialWrongCard); consumed = true; } } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_initial_wrong_card.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_initial_wrong_card.c new file mode 100644 index 0000000000..c2c36c74fa --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_initial_wrong_card.c @@ -0,0 +1,58 @@ +#include "../nfc_app_i.h" + +void nfc_scene_mf_classic_update_initial_wrong_card_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + NfcApp* instance = context; + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(instance->view_dispatcher, result); + } +} + +void nfc_scene_mf_classic_update_initial_wrong_card_on_enter(void* context) { + NfcApp* instance = context; + Widget* widget = instance->widget; + + notification_message(instance->notifications, &sequence_error); + + widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42); + widget_add_string_element(widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Wrong Card!"); + widget_add_string_multiline_element( + widget, + 4, + 17, + AlignLeft, + AlignTop, + FontSecondary, + "Data management\nis only possible\nwith source card"); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Retry", + nfc_scene_mf_classic_update_initial_wrong_card_widget_callback, + instance); + + // Setup and start worker + view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget); +} + +bool nfc_scene_mf_classic_update_initial_wrong_card_on_event( + void* context, + SceneManagerEvent event) { + NfcApp* instance = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + consumed = scene_manager_previous_scene(instance->scene_manager); + } + } + return consumed; +} + +void nfc_scene_mf_classic_update_initial_wrong_card_on_exit(void* context) { + NfcApp* instance = context; + + widget_reset(instance->widget); +} \ No newline at end of file diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_initial.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_initial.c index da576a276c..12e7ba1ecd 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_initial.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_initial.c @@ -67,7 +67,7 @@ static void nfc_scene_mf_classic_write_initial_setup_view(NfcApp* instance) { if(state == NfcSceneMfClassicWriteInitialStateCardSearch) { popup_set_header(instance->popup, "Writing", 95, 20, AlignCenter, AlignCenter); popup_set_text( - instance->popup, "Apply the initial\ncard only", 95, 38, AlignCenter, AlignCenter); + instance->popup, "Use the source\ncard only", 95, 38, AlignCenter, AlignCenter); popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50); } else { popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter); @@ -115,7 +115,8 @@ bool nfc_scene_mf_classic_write_initial_on_event(void* context, SceneManagerEven nfc_scene_mf_classic_write_initial_setup_view(instance); consumed = true; } else if(event.event == NfcCustomEventWrongCard) { - scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWrongCard); + scene_manager_next_scene( + instance->scene_manager, NfcSceneMfClassicWriteInitialWrongCard); consumed = true; } else if(event.event == NfcCustomEventPollerSuccess) { scene_manager_next_scene( diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_wrong_card.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_initial_wrong_card.c similarity index 69% rename from applications/main/nfc/scenes/nfc_scene_mf_classic_wrong_card.c rename to applications/main/nfc/scenes/nfc_scene_mf_classic_write_initial_wrong_card.c index a879985bc8..3f92ebfd3b 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_wrong_card.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_initial_wrong_card.c @@ -1,6 +1,6 @@ #include "../nfc_app_i.h" -void nfc_scene_mf_classic_wrong_card_widget_callback( +void nfc_scene_mf_classic_write_initial_wrong_card_widget_callback( GuiButtonType result, InputType type, void* context) { @@ -10,7 +10,7 @@ void nfc_scene_mf_classic_wrong_card_widget_callback( } } -void nfc_scene_mf_classic_wrong_card_on_enter(void* context) { +void nfc_scene_mf_classic_write_initial_wrong_card_on_enter(void* context) { NfcApp* instance = context; Widget* widget = instance->widget; @@ -18,7 +18,7 @@ void nfc_scene_mf_classic_wrong_card_on_enter(void* context) { widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42); widget_add_string_element( - widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "This is wrong card"); + widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Use The Source Card!"); widget_add_string_multiline_element( widget, 4, @@ -26,19 +26,19 @@ void nfc_scene_mf_classic_wrong_card_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - "Data management\nis only possible\nwith initial card"); + "Go to NFC Magic\napp if you want to\nwrite blanks"); widget_add_button_element( widget, GuiButtonTypeLeft, "Retry", - nfc_scene_mf_classic_wrong_card_widget_callback, + nfc_scene_mf_classic_write_initial_wrong_card_widget_callback, instance); // Setup and start worker view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget); } -bool nfc_scene_mf_classic_wrong_card_on_event(void* context, SceneManagerEvent event) { +bool nfc_scene_mf_classic_write_initial_wrong_card_on_event(void* context, SceneManagerEvent event) { NfcApp* instance = context; bool consumed = false; @@ -50,7 +50,7 @@ bool nfc_scene_mf_classic_wrong_card_on_event(void* context, SceneManagerEvent e return consumed; } -void nfc_scene_mf_classic_wrong_card_on_exit(void* context) { +void nfc_scene_mf_classic_write_initial_wrong_card_on_exit(void* context) { NfcApp* instance = context; widget_reset(instance->widget); diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c index db5fd945fa..4df8a62899 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c @@ -22,14 +22,14 @@ void nfc_scene_mf_ultralight_unlock_warn_on_enter(void* context) { for(size_t i = 0; i < sizeof(nfc->mf_ul_auth->password.data); i++) { furi_string_cat_printf(password_str, "%02X ", nfc->mf_ul_auth->password.data[i]); } - furi_string_cat_str(password_str, "?\nCaution, a wrong password\ncan block the card!"); + furi_string_cat_str(password_str, "\nWarning: incorrect password\nwill block the card!"); nfc_text_store_set(nfc, furi_string_get_cstr(password_str)); furi_string_free(password_str); - const char* message = (type == MfUltralightAuthTypeReader) ? "Password captured!" : - "Risky function!"; + const char* message = (type == MfUltralightAuthTypeReader) ? "Password Captured!" : + "Risky Action!"; dialog_ex_set_header(dialog_ex, message, 64, 0, AlignCenter, AlignTop); - dialog_ex_set_text(dialog_ex, nfc->text_store, 64, 12, AlignCenter, AlignTop); + dialog_ex_set_text(dialog_ex, nfc->text_store, 64, 10, AlignCenter, AlignTop); dialog_ex_set_left_button_text(dialog_ex, "Cancel"); dialog_ex_set_right_button_text(dialog_ex, "Continue"); @@ -37,7 +37,7 @@ void nfc_scene_mf_ultralight_unlock_warn_on_enter(void* context) { notification_message(nfc->notifications, &sequence_set_green_255); } } else { - dialog_ex_set_header(dialog_ex, "Risky function!", 64, 4, AlignCenter, AlignTop); + dialog_ex_set_header(dialog_ex, "Risky action!", 64, 4, AlignCenter, AlignTop); dialog_ex_set_text( dialog_ex, "Wrong password\ncan block your\ncard.", 4, 18, AlignLeft, AlignTop); dialog_ex_set_icon(dialog_ex, 83, 22, &I_WarningDolphinFlip_45x42); diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c index b01876e068..ae725ce679 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c @@ -32,7 +32,7 @@ void nfc_scene_slix_unlock_on_enter(void* context) { popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50); popup_set_header(instance->popup, "Unlocking", 97, 15, AlignCenter, AlignTop); popup_set_text( - instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop); + instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop); view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup); instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolSlix); diff --git a/applications/system/js_app/examples/apps/Scripts/badusb_demo.js b/applications/system/js_app/examples/apps/Scripts/badusb_demo.js index bbeedd4457..8605020233 100644 --- a/applications/system/js_app/examples/apps/Scripts/badusb_demo.js +++ b/applications/system/js_app/examples/apps/Scripts/badusb_demo.js @@ -26,6 +26,12 @@ if (badusb.isConnected()) { badusb.println("Flipper Name: " + flipper.getName()); badusb.println("Battery level: " + to_string(flipper.getBatteryCharge()) + "%"); + // Alt+Numpad method works only on Windows!!! + badusb.altPrintln("This was printed with Alt+Numpad method!"); + + // There's also badusb.print() and badusb.altPrint() + // which don't add the return at the end + notify.success(); } else { print("USB not connected"); diff --git a/applications/system/js_app/examples/apps/Scripts/keyboard.js b/applications/system/js_app/examples/apps/Scripts/keyboard.js index a34607c299..2b01418de8 100644 --- a/applications/system/js_app/examples/apps/Scripts/keyboard.js +++ b/applications/system/js_app/examples/apps/Scripts/keyboard.js @@ -4,16 +4,20 @@ keyboard.setHeader("Example Text Input"); // Default text is optional let text = keyboard.text(100, "Default text", true); +// Returns undefined when pressing back print("Got text:", text); keyboard.setHeader("Example Byte Input"); // Default data is optional -let data = keyboard.byte(6, Uint8Array([1, 2, 3, 4, 5, 6])); -data = Uint8Array(data); -let result = "0x"; -for (let i = 0; i < data.byteLength; i++) { - if (data[i] < 0x10) result += "0"; - result += to_hex_string(data[i]); +let result = keyboard.byte(6, Uint8Array([1, 2, 3, 4, 5, 6])); +// Returns undefined when pressing back +if (result !== undefined) { + let data = Uint8Array(result); + result = "0x"; + for (let i = 0; i < data.byteLength; i++) { + if (data[i] < 0x10) result += "0"; + result += to_hex_string(data[i]); + } } print("Got data:", result); \ No newline at end of file diff --git a/applications/system/js_app/examples/apps/Scripts/stringutils.js b/applications/system/js_app/examples/apps/Scripts/stringutils.js new file mode 100644 index 0000000000..51781328df --- /dev/null +++ b/applications/system/js_app/examples/apps/Scripts/stringutils.js @@ -0,0 +1,19 @@ +let sampleText = "Hello, World!"; + +let lengthOfText = "Length of text: " + to_string(sampleText.length); +print(lengthOfText); + +let start = 7; +let end = 12; +let substringResult = sampleText.slice(start, end); +print(substringResult); + +let searchStr = "World"; +let result2 = to_string(sampleText.indexOf(searchStr)); +print(result2); + +let upperCaseText = "Text in upper case: " + to_upper_case(sampleText); +print(upperCaseText); + +let lowerCaseText = "Text in lower case: " + to_lower_case(sampleText); +print(lowerCaseText); diff --git a/applications/system/js_app/examples/apps/Scripts/submenu.js b/applications/system/js_app/examples/apps/Scripts/submenu.js index 6744ca4526..2455513093 100644 --- a/applications/system/js_app/examples/apps/Scripts/submenu.js +++ b/applications/system/js_app/examples/apps/Scripts/submenu.js @@ -7,5 +7,5 @@ submenu.addItem("Item 3", 2); submenu.setHeader("Select an option:"); let result = submenu.show(); - +// Returns undefined when pressing back print("Result:", result); diff --git a/applications/system/js_app/js_thread.c b/applications/system/js_app/js_thread.c index 5ca3654041..ceaad5e36c 100644 --- a/applications/system/js_app/js_thread.c +++ b/applications/system/js_app/js_thread.c @@ -195,7 +195,7 @@ static void js_require(struct mjs* mjs) { } static void js_global_to_string(struct mjs* mjs) { - double num = mjs_get_int(mjs, mjs_arg(mjs, 0)); + double num = mjs_get_double(mjs, mjs_arg(mjs, 0)); char tmp_str[] = "-2147483648"; itoa(num, tmp_str, 10); mjs_val_t ret = mjs_mk_string(mjs, tmp_str, ~0, true); @@ -210,6 +210,88 @@ static void js_global_to_hex_string(struct mjs* mjs) { mjs_return(mjs, ret); } +static void js_parse_int(struct mjs* mjs) { + mjs_val_t arg = mjs_arg(mjs, 0); + if(!mjs_is_string(arg)) { + mjs_return(mjs, mjs_mk_number(mjs, 0)); + return; + } + size_t str_len = 0; + const char* str = mjs_get_string(mjs, &arg, &str_len); + if((str_len == 0) || (str == NULL)) { + mjs_return(mjs, mjs_mk_number(mjs, 0)); + return; + } + + int32_t num = 0; + int32_t sign = 1; + size_t i = 0; + + if(str[0] == '-') { + sign = -1; + i = 1; + } else if(str[0] == '+') { + i = 1; + } + + for(; i < str_len; i++) { + if(str[i] >= '0' && str[i] <= '9') { + num = num * 10 + (str[i] - '0'); + } else { + break; + } + } + num *= sign; + + mjs_return(mjs, mjs_mk_number(mjs, num)); +} + +static void js_to_upper_case(struct mjs* mjs) { + mjs_val_t arg0 = mjs_arg(mjs, 0); + + size_t str_len; + const char* str = NULL; + if(mjs_is_string(arg0)) { + str = mjs_get_string(mjs, &arg0, &str_len); + } + if(!str) { + mjs_return(mjs, MJS_UNDEFINED); + return; + } + + char* upperStr = strdup(str); + for(size_t i = 0; i < str_len; i++) { + upperStr[i] = toupper(upperStr[i]); + } + + mjs_val_t resultStr = mjs_mk_string(mjs, upperStr, ~0, true); + free(upperStr); + mjs_return(mjs, resultStr); +} + +static void js_to_lower_case(struct mjs* mjs) { + mjs_val_t arg0 = mjs_arg(mjs, 0); + + size_t str_len; + const char* str = NULL; + if(mjs_is_string(arg0)) { + str = mjs_get_string(mjs, &arg0, &str_len); + } + if(!str) { + mjs_return(mjs, MJS_UNDEFINED); + return; + } + + char* lowerStr = strdup(str); + for(size_t i = 0; i < str_len; i++) { + lowerStr[i] = tolower(lowerStr[i]); + } + + mjs_val_t resultStr = mjs_mk_string(mjs, lowerStr, ~0, true); + free(lowerStr); + mjs_return(mjs, resultStr); +} + #ifdef JS_DEBUG static void js_dump_write_callback(void* ctx, const char* format, ...) { File* file = ctx; @@ -243,6 +325,9 @@ static int32_t js_thread(void* arg) { mjs_set(mjs, global, "to_hex_string", ~0, MJS_MK_FN(js_global_to_hex_string)); mjs_set(mjs, global, "ffi_address", ~0, MJS_MK_FN(js_ffi_address)); mjs_set(mjs, global, "require", ~0, MJS_MK_FN(js_require)); + mjs_set(mjs, global, "parse_int", ~0, MJS_MK_FN(js_parse_int)); + mjs_set(mjs, global, "to_upper_case", ~0, MJS_MK_FN(js_to_upper_case)); + mjs_set(mjs, global, "to_lower_case", ~0, MJS_MK_FN(js_to_lower_case)); mjs_val_t console_obj = mjs_mk_object(mjs); mjs_set(mjs, console_obj, "log", ~0, MJS_MK_FN(js_console_log)); diff --git a/applications/system/js_app/modules/js_badusb.c b/applications/system/js_app/modules/js_badusb.c index 0ac5c47da2..389539be58 100644 --- a/applications/system/js_app/modules/js_badusb.c +++ b/applications/system/js_app/modules/js_badusb.c @@ -52,6 +52,17 @@ static const struct { {"F10", HID_KEYBOARD_F10}, {"F11", HID_KEYBOARD_F11}, {"F12", HID_KEYBOARD_F12}, + + {"NUM0", HID_KEYPAD_0}, + {"NUM1", HID_KEYPAD_1}, + {"NUM2", HID_KEYPAD_2}, + {"NUM3", HID_KEYPAD_3}, + {"NUM4", HID_KEYPAD_4}, + {"NUM5", HID_KEYPAD_5}, + {"NUM6", HID_KEYPAD_6}, + {"NUM7", HID_KEYPAD_7}, + {"NUM8", HID_KEYPAD_8}, + {"NUM9", HID_KEYPAD_9}, }; static void js_badusb_quit_free(JsBadusbInst* badusb) { @@ -314,7 +325,35 @@ static void js_badusb_release(struct mjs* mjs) { mjs_return(mjs, MJS_UNDEFINED); } -static void badusb_print(struct mjs* mjs, bool ln) { +// Make sure NUMLOCK is enabled for altchar +static void ducky_numlock_on() { + if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) { + furi_hal_hid_kb_press(HID_KEYBOARD_LOCK_NUM_LOCK); + furi_hal_hid_kb_release(HID_KEYBOARD_LOCK_NUM_LOCK); + } +} + +// Simulate pressing a character using ALT+Numpad ASCII code +static void ducky_altchar(const char* ascii_code) { + // Hold the ALT key + furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); + + // Press the corresponding numpad key for each digit of the ASCII code + for(size_t i = 0; ascii_code[i] != '\0'; i++) { + char digitChar[5] = {'N', 'U', 'M', ascii_code[i], '\0'}; // Construct the numpad key name + uint16_t numpad_keycode = get_keycode_by_name(digitChar, strlen(digitChar)); + if(numpad_keycode == HID_KEYBOARD_NONE) { + continue; // Skip if keycode not found + } + furi_hal_hid_kb_press(numpad_keycode); + furi_hal_hid_kb_release(numpad_keycode); + } + + // Release the ALT key + furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT); +} + +static void badusb_print(struct mjs* mjs, bool ln, bool alt) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); JsBadusbInst* badusb = mjs_get_ptr(mjs, obj_inst); furi_assert(badusb); @@ -360,10 +399,20 @@ static void badusb_print(struct mjs* mjs, bool ln) { return; } + if(alt) { + ducky_numlock_on(); + } for(size_t i = 0; i < text_len; i++) { - uint16_t keycode = HID_ASCII_TO_KEY(text_str[i]); - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); + if(alt) { + // Convert character to ascii numeric value + char ascii_str[4]; + snprintf(ascii_str, sizeof(ascii_str), "%u", (uint8_t)text_str[i]); + ducky_altchar(ascii_str); + } else { + uint16_t keycode = HID_ASCII_TO_KEY(text_str[i]); + furi_hal_hid_kb_press(keycode); + furi_hal_hid_kb_release(keycode); + } if(delay_val > 0) { bool need_exit = js_delay_with_flags(mjs, delay_val); if(need_exit) { @@ -381,11 +430,19 @@ static void badusb_print(struct mjs* mjs, bool ln) { } static void js_badusb_print(struct mjs* mjs) { - badusb_print(mjs, false); + badusb_print(mjs, false, false); } static void js_badusb_println(struct mjs* mjs) { - badusb_print(mjs, true); + badusb_print(mjs, true, false); +} + +static void js_badusb_alt_print(struct mjs* mjs) { + badusb_print(mjs, false, true); +} + +static void js_badusb_alt_println(struct mjs* mjs) { + badusb_print(mjs, true, true); } static void* js_badusb_create(struct mjs* mjs, mjs_val_t* object) { @@ -400,6 +457,8 @@ static void* js_badusb_create(struct mjs* mjs, mjs_val_t* object) { mjs_set(mjs, badusb_obj, "release", ~0, MJS_MK_FN(js_badusb_release)); mjs_set(mjs, badusb_obj, "print", ~0, MJS_MK_FN(js_badusb_print)); mjs_set(mjs, badusb_obj, "println", ~0, MJS_MK_FN(js_badusb_println)); + mjs_set(mjs, badusb_obj, "altPrint", ~0, MJS_MK_FN(js_badusb_alt_print)); + mjs_set(mjs, badusb_obj, "altPrintln", ~0, MJS_MK_FN(js_badusb_alt_println)); *object = badusb_obj; return badusb; } diff --git a/applications/system/js_app/modules/js_blebeacon.c b/applications/system/js_app/modules/js_blebeacon.c index 4d19accb1c..4b661a2cf6 100644 --- a/applications/system/js_app/modules/js_blebeacon.c +++ b/applications/system/js_app/modules/js_blebeacon.c @@ -43,16 +43,6 @@ static bool check_arg_count(struct mjs* mjs, size_t count) { return true; } -static bool get_int_arg(struct mjs* mjs, size_t index, uint8_t* value, bool error) { - mjs_val_t int_obj = mjs_arg(mjs, index); - if(!mjs_is_number(int_obj)) { - if(error) ret_bad_args(mjs, "Argument must be a number"); - return false; - } - *value = mjs_get_int(mjs, int_obj); - return true; -} - static void js_blebeacon_is_active(struct mjs* mjs) { JsBlebeaconInst* blebeacon = get_this_ctx(mjs); if(!check_arg_count(mjs, 0)) return; @@ -83,15 +73,24 @@ static void js_blebeacon_set_config(struct mjs* mjs) { } uint8_t power = GapAdvPowerLevel_0dBm; - get_int_arg(mjs, 1, &power, false); + mjs_val_t power_arg = mjs_arg(mjs, 1); + if(mjs_is_number(power_arg)) { + power = mjs_get_int32(mjs, power_arg); + } power = CLAMP(power, GapAdvPowerLevel_6dBm, GapAdvPowerLevel_Neg40dBm); uint8_t intv_min = 50; - get_int_arg(mjs, 2, &intv_min, false); + mjs_val_t intv_min_arg = mjs_arg(mjs, 2); + if(mjs_is_number(intv_min_arg)) { + intv_min = mjs_get_int32(mjs, intv_min_arg); + } intv_min = MAX(intv_min, 20); uint8_t intv_max = 150; - get_int_arg(mjs, 3, &intv_max, false); + mjs_val_t intv_max_arg = mjs_arg(mjs, 3); + if(mjs_is_number(intv_max_arg)) { + intv_max = mjs_get_int32(mjs, intv_max_arg); + } intv_max = MAX(intv_max, intv_min); GapExtraBeaconConfig config = { diff --git a/applications/system/js_app/modules/js_dialog.c b/applications/system/js_app/modules/js_dialog.c index a457d700c9..1a8ce5a64a 100644 --- a/applications/system/js_app/modules/js_dialog.c +++ b/applications/system/js_app/modules/js_dialog.c @@ -3,6 +3,18 @@ #include #include +// File icon +#include +static const uint8_t _I_file_10px_0[] = { + 0x00, 0x7f, 0x00, 0xa1, 0x00, 0x2d, 0x01, 0xe1, 0x01, 0x0d, 0x01, + 0x01, 0x01, 0x7d, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, +}; +static const uint8_t* const _I_file_10px[] = {_I_file_10px_0}; + +static const Icon I_file_10px = + {.width = 10, .height = 10, .frame_count = 1, .frame_rate = 0, .frames = _I_file_10px}; +// File icon end + static bool js_dialog_msg_parse_params(struct mjs* mjs, const char** hdr, const char** msg) { size_t num_args = mjs_nargs(mjs); if(num_args != 2) { @@ -167,7 +179,7 @@ static void js_dialog_pick_file(struct mjs* mjs) { DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); const DialogsFileBrowserOptions browser_options = { .extension = extension, - .icon = &I_Apps_10px, + .icon = &I_file_10px, .base_path = base_path, }; FuriString* path = furi_string_alloc_set(base_path); diff --git a/applications/system/js_app/modules/js_keyboard.c b/applications/system/js_app/modules/js_keyboard.c index 8958dcaf8c..6d7ce0e579 100644 --- a/applications/system/js_app/modules/js_keyboard.c +++ b/applications/system/js_app/modules/js_keyboard.c @@ -6,48 +6,18 @@ #define membersof(x) (sizeof(x) / sizeof(x[0])) typedef struct { - char* data; TextInput* text_input; ByteInput* byte_input; ViewDispatcher* view_dispatcher; - uint8_t* byteinput; + char* header; + bool accepted; } JsKeyboardInst; -typedef enum { - JsKeyboardViewTextInput, - JsKeyboardViewByteInput, -} JsKeyboardView; - static void ret_bad_args(struct mjs* mjs, const char* error) { mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "%s", error); mjs_return(mjs, MJS_UNDEFINED); } -static bool get_str_arg(struct mjs* mjs, size_t index, const char** value, bool error) { - mjs_val_t str_obj = mjs_arg(mjs, index); - if(!mjs_is_string(str_obj)) { - if(error) ret_bad_args(mjs, "Argument must be a string"); - return false; - } - size_t str_len = 0; - *value = mjs_get_string(mjs, &str_obj, &str_len); - if((str_len == 0) || (*value == NULL)) { - if(error) ret_bad_args(mjs, "Bad string argument"); - return false; - } - return true; -} - -static bool get_int_arg(struct mjs* mjs, size_t index, size_t* value, bool error) { - mjs_val_t int_obj = mjs_arg(mjs, index); - if(!mjs_is_number(int_obj)) { - if(error) ret_bad_args(mjs, "Argument must be a number"); - return false; - } - *value = mjs_get_int(mjs, int_obj); - return true; -} - static JsKeyboardInst* get_this_ctx(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); JsKeyboardInst* storage = mjs_get_ptr(mjs, obj_inst); @@ -55,24 +25,33 @@ static JsKeyboardInst* get_this_ctx(struct mjs* mjs) { return storage; } -void text_input_callback(void* context) { +static void keyboard_callback(void* context) { JsKeyboardInst* keyboard = (JsKeyboardInst*)context; + keyboard->accepted = true; view_dispatcher_stop(keyboard->view_dispatcher); } -void byte_input_callback(void* context) { +static bool keyboard_exit(void* context) { JsKeyboardInst* keyboard = (JsKeyboardInst*)context; + keyboard->accepted = false; view_dispatcher_stop(keyboard->view_dispatcher); + return true; } static void js_keyboard_set_header(struct mjs* mjs) { JsKeyboardInst* keyboard = get_this_ctx(mjs); - const char* header; - if(!get_str_arg(mjs, 0, &header, true)) return; + mjs_val_t header_arg = mjs_arg(mjs, 0); + const char* header = mjs_get_string(mjs, &header_arg, NULL); + if(!header) { + ret_bad_args(mjs, "Header must be a string"); + return; + } - text_input_set_header_text(keyboard->text_input, header); - byte_input_set_header_text(keyboard->byte_input, header); + if(keyboard->header) { + free(keyboard->header); + } + keyboard->header = strdup(header); mjs_return(mjs, MJS_UNDEFINED); } @@ -80,40 +59,70 @@ static void js_keyboard_set_header(struct mjs* mjs) { static void js_keyboard_text(struct mjs* mjs) { JsKeyboardInst* keyboard = get_this_ctx(mjs); - size_t input_length; - if(!get_int_arg(mjs, 0, &input_length, true)) return; + mjs_val_t input_length_arg = mjs_arg(mjs, 0); + if(!mjs_is_number(input_length_arg)) { + ret_bad_args(mjs, "Input length must be a number"); + return; + } + int32_t input_length = mjs_get_int32(mjs, input_length_arg); char* buffer = malloc(input_length); - const char* default_text = ""; + mjs_val_t default_text_arg = mjs_arg(mjs, 1); + const char* default_text = mjs_get_string(mjs, &default_text_arg, NULL); bool clear_default = false; - if(get_str_arg(mjs, 1, &default_text, false)) { + if(default_text) { strlcpy(buffer, default_text, input_length); mjs_val_t bool_obj = mjs_arg(mjs, 2); clear_default = mjs_get_bool(mjs, bool_obj); } - view_dispatcher_attach_to_gui( - keyboard->view_dispatcher, furi_record_open(RECORD_GUI), ViewDispatcherTypeFullscreen); - furi_record_close(RECORD_GUI); - + if(keyboard->header) { + text_input_set_header_text(keyboard->text_input, keyboard->header); + } text_input_set_result_callback( - keyboard->text_input, text_input_callback, keyboard, buffer, input_length, clear_default); + keyboard->text_input, keyboard_callback, keyboard, buffer, input_length, clear_default); - view_dispatcher_switch_to_view(keyboard->view_dispatcher, JsKeyboardViewTextInput); + text_input_set_minimum_length(keyboard->text_input, 0); + + Gui* gui = furi_record_open(RECORD_GUI); + keyboard->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(keyboard->view_dispatcher); + view_dispatcher_add_view( + keyboard->view_dispatcher, 0, text_input_get_view(keyboard->text_input)); + view_dispatcher_set_event_callback_context(keyboard->view_dispatcher, keyboard); + view_dispatcher_set_navigation_event_callback(keyboard->view_dispatcher, keyboard_exit); + view_dispatcher_attach_to_gui(keyboard->view_dispatcher, gui, ViewDispatcherTypeFullscreen); + view_dispatcher_switch_to_view(keyboard->view_dispatcher, 0); view_dispatcher_run(keyboard->view_dispatcher); - text_input_reset(keyboard->text_input); + view_dispatcher_remove_view(keyboard->view_dispatcher, 0); + view_dispatcher_free(keyboard->view_dispatcher); + keyboard->view_dispatcher = NULL; + furi_record_close(RECORD_GUI); - mjs_return(mjs, mjs_mk_string(mjs, buffer, ~0, true)); + text_input_reset(keyboard->text_input); + if(keyboard->header) { + free(keyboard->header); + keyboard->header = NULL; + } + if(keyboard->accepted) { + mjs_return(mjs, mjs_mk_string(mjs, buffer, ~0, true)); + } else { + mjs_return(mjs, MJS_UNDEFINED); + } free(buffer); } static void js_keyboard_byte(struct mjs* mjs) { JsKeyboardInst* keyboard = get_this_ctx(mjs); - size_t input_length; - if(!get_int_arg(mjs, 0, &input_length, true)) return; + mjs_val_t input_length_arg = mjs_arg(mjs, 0); + if(!mjs_is_number(input_length_arg)) { + ret_bad_args(mjs, "Input length must be a number"); + return; + } + int32_t input_length = mjs_get_int32(mjs, input_length_arg); uint8_t* buffer = malloc(input_length); mjs_val_t default_data_arg = mjs_arg(mjs, 1); @@ -126,21 +135,40 @@ static void js_keyboard_byte(struct mjs* mjs) { memcpy(buffer, (uint8_t*)default_data, MIN((size_t)input_length, default_data_len)); } - view_dispatcher_attach_to_gui( - keyboard->view_dispatcher, furi_record_open(RECORD_GUI), ViewDispatcherTypeFullscreen); - furi_record_close(RECORD_GUI); - + if(keyboard->header) { + byte_input_set_header_text(keyboard->byte_input, keyboard->header); + } byte_input_set_result_callback( - keyboard->byte_input, byte_input_callback, NULL, keyboard, buffer, input_length); + keyboard->byte_input, keyboard_callback, NULL, keyboard, buffer, input_length); - view_dispatcher_switch_to_view(keyboard->view_dispatcher, JsKeyboardViewByteInput); + Gui* gui = furi_record_open(RECORD_GUI); + keyboard->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(keyboard->view_dispatcher); + view_dispatcher_add_view( + keyboard->view_dispatcher, 0, byte_input_get_view(keyboard->byte_input)); + view_dispatcher_set_event_callback_context(keyboard->view_dispatcher, keyboard); + view_dispatcher_set_navigation_event_callback(keyboard->view_dispatcher, keyboard_exit); + view_dispatcher_attach_to_gui(keyboard->view_dispatcher, gui, ViewDispatcherTypeFullscreen); + view_dispatcher_switch_to_view(keyboard->view_dispatcher, 0); view_dispatcher_run(keyboard->view_dispatcher); + view_dispatcher_remove_view(keyboard->view_dispatcher, 0); + view_dispatcher_free(keyboard->view_dispatcher); + keyboard->view_dispatcher = NULL; + furi_record_close(RECORD_GUI); + + if(keyboard->header) { + free(keyboard->header); + keyboard->header = NULL; + } byte_input_set_result_callback(keyboard->byte_input, NULL, NULL, NULL, NULL, 0); byte_input_set_header_text(keyboard->byte_input, ""); - - mjs_return(mjs, mjs_mk_array_buf(mjs, (char*)buffer, input_length)); + if(keyboard->accepted) { + mjs_return(mjs, mjs_mk_array_buf(mjs, (char*)buffer, input_length)); + } else { + mjs_return(mjs, MJS_UNDEFINED); + } free(buffer); } @@ -153,28 +181,14 @@ static void* js_keyboard_create(struct mjs* mjs, mjs_val_t* object) { mjs_set(mjs, keyboard_obj, "byte", ~0, MJS_MK_FN(js_keyboard_byte)); keyboard->byte_input = byte_input_alloc(); keyboard->text_input = text_input_alloc(); - keyboard->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(keyboard->view_dispatcher); - view_dispatcher_add_view( - keyboard->view_dispatcher, - JsKeyboardViewTextInput, - text_input_get_view(keyboard->text_input)); - view_dispatcher_add_view( - keyboard->view_dispatcher, - JsKeyboardViewByteInput, - byte_input_get_view(keyboard->byte_input)); *object = keyboard_obj; return keyboard; } static void js_keyboard_destroy(void* inst) { JsKeyboardInst* keyboard = inst; - view_dispatcher_remove_view(keyboard->view_dispatcher, JsKeyboardViewByteInput); byte_input_free(keyboard->byte_input); - view_dispatcher_remove_view(keyboard->view_dispatcher, JsKeyboardViewTextInput); text_input_free(keyboard->text_input); - view_dispatcher_free(keyboard->view_dispatcher); - free(keyboard->data); free(keyboard); } diff --git a/applications/system/js_app/modules/js_subghz/js_subghz.c b/applications/system/js_app/modules/js_subghz/js_subghz.c index 913f8c670d..f170aa04bc 100644 --- a/applications/system/js_app/modules/js_subghz/js_subghz.c +++ b/applications/system/js_app/modules/js_subghz/js_subghz.c @@ -41,17 +41,6 @@ static FuriHalSubGhzPreset js_subghz_get_preset_name(const char* preset_name) { return preset; } -static int32_t get_int_arg(struct mjs* mjs, size_t index, int32_t* value) { - mjs_val_t int_obj = mjs_arg(mjs, index); - if(!mjs_is_number(int_obj)) { - mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "Argument must be a number"); - mjs_return(mjs, MJS_UNDEFINED); - return false; - } - *value = mjs_get_int(mjs, int_obj); - return true; -} - static void js_subghz_set_rx(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); JsSubghzInst* js_subghz = mjs_get_ptr(mjs, obj_inst); @@ -137,8 +126,13 @@ static void js_subghz_set_frequency(struct mjs* mjs) { return; } - int32_t frequency; - if(!get_int_arg(mjs, 0, &frequency)) return; + mjs_val_t frequency_arg = mjs_arg(mjs, 0); + if(!mjs_is_number(frequency_arg)) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Frequency must be a number"); + mjs_return(mjs, MJS_UNDEFINED); + return; + } + int32_t frequency = mjs_get_int32(mjs, frequency_arg); if(!subghz_devices_is_frequency_valid(js_subghz->radio_device, frequency)) { mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Invalid frequency"); diff --git a/applications/system/js_app/modules/js_submenu.c b/applications/system/js_app/modules/js_submenu.c index b87f34fa8b..1d2f5db554 100644 --- a/applications/system/js_app/modules/js_submenu.c +++ b/applications/system/js_app/modules/js_submenu.c @@ -7,12 +7,9 @@ typedef struct { Submenu* submenu; ViewDispatcher* view_dispatcher; uint32_t result; + bool accepted; } JsSubmenuInst; -typedef enum { - JsSubmenuViewSubmenu, -} JsSubmenuView; - static JsSubmenuInst* get_this_ctx(struct mjs* mjs) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); JsSubmenuInst* storage = mjs_get_ptr(mjs, obj_inst); @@ -34,47 +31,38 @@ static bool check_arg_count(struct mjs* mjs, size_t count) { return true; } -static bool get_str_arg(struct mjs* mjs, size_t index, const char** value) { - mjs_val_t str_obj = mjs_arg(mjs, index); - if(!mjs_is_string(str_obj)) { - ret_bad_args(mjs, "Argument must be a string"); - return false; - } - size_t str_len = 0; - *value = mjs_get_string(mjs, &str_obj, &str_len); - if((str_len == 0) || (*value == NULL)) { - ret_bad_args(mjs, "Bad string argument"); - return false; - } - return true; -} - -static int32_t get_int_arg(struct mjs* mjs, size_t index, int32_t* value) { - mjs_val_t int_obj = mjs_arg(mjs, index); - if(!mjs_is_number(int_obj)) { - ret_bad_args(mjs, "Argument must be a number"); - return false; - } - *value = mjs_get_int32(mjs, int_obj); - return true; -} - static void submenu_callback(void* context, uint32_t id) { - UNUSED(id); JsSubmenuInst* submenu = context; submenu->result = id; + submenu->accepted = true; view_dispatcher_stop(submenu->view_dispatcher); } +static bool submenu_exit(void* context) { + JsSubmenuInst* submenu = context; + submenu->result = 0; + submenu->accepted = false; + view_dispatcher_stop(submenu->view_dispatcher); + return true; +} + static void js_submenu_add_item(struct mjs* mjs) { JsSubmenuInst* submenu = get_this_ctx(mjs); if(!check_arg_count(mjs, 2)) return; - const char* label; - if(!get_str_arg(mjs, 0, &label)) return; + mjs_val_t label_arg = mjs_arg(mjs, 0); + const char* label = mjs_get_string(mjs, &label_arg, NULL); + if(!label) { + ret_bad_args(mjs, "Label must be a string"); + return; + } - int32_t id; - if(!get_int_arg(mjs, 1, &id)) return; + mjs_val_t id_arg = mjs_arg(mjs, 1); + if(!mjs_is_number(id_arg)) { + ret_bad_args(mjs, "Id must be a number"); + return; + } + int32_t id = mjs_get_int32(mjs, id_arg); submenu_add_item(submenu->submenu, label, id, submenu_callback, submenu); @@ -85,8 +73,12 @@ static void js_submenu_set_header(struct mjs* mjs) { JsSubmenuInst* submenu = get_this_ctx(mjs); if(!check_arg_count(mjs, 1)) return; - const char* header; - if(!get_str_arg(mjs, 0, &header)) return; + mjs_val_t header_arg = mjs_arg(mjs, 0); + const char* header = mjs_get_string(mjs, &header_arg, NULL); + if(!header) { + ret_bad_args(mjs, "Header must be a string"); + return; + } submenu_set_header(submenu->submenu, header); @@ -96,19 +88,29 @@ static void js_submenu_set_header(struct mjs* mjs) { static void js_submenu_show(struct mjs* mjs) { JsSubmenuInst* submenu = get_this_ctx(mjs); if(!check_arg_count(mjs, 0)) return; - submenu->result = 0; - view_dispatcher_attach_to_gui( - submenu->view_dispatcher, furi_record_open(RECORD_GUI), ViewDispatcherTypeFullscreen); - furi_record_close(RECORD_GUI); - - view_dispatcher_switch_to_view(submenu->view_dispatcher, JsSubmenuViewSubmenu); + Gui* gui = furi_record_open(RECORD_GUI); + submenu->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(submenu->view_dispatcher); + view_dispatcher_add_view(submenu->view_dispatcher, 0, submenu_get_view(submenu->submenu)); + view_dispatcher_set_event_callback_context(submenu->view_dispatcher, submenu); + view_dispatcher_set_navigation_event_callback(submenu->view_dispatcher, submenu_exit); + view_dispatcher_attach_to_gui(submenu->view_dispatcher, gui, ViewDispatcherTypeFullscreen); + view_dispatcher_switch_to_view(submenu->view_dispatcher, 0); view_dispatcher_run(submenu->view_dispatcher); - submenu_reset(submenu->submenu); + view_dispatcher_remove_view(submenu->view_dispatcher, 0); + view_dispatcher_free(submenu->view_dispatcher); + submenu->view_dispatcher = NULL; + furi_record_close(RECORD_GUI); - mjs_return(mjs, mjs_mk_number(mjs, submenu->result)); + submenu_reset(submenu->submenu); + if(submenu->accepted) { + mjs_return(mjs, mjs_mk_number(mjs, submenu->result)); + } else { + mjs_return(mjs, MJS_UNDEFINED); + } } static void* js_submenu_create(struct mjs* mjs, mjs_val_t* object) { @@ -119,19 +121,13 @@ static void* js_submenu_create(struct mjs* mjs, mjs_val_t* object) { mjs_set(mjs, submenu_obj, "setHeader", ~0, MJS_MK_FN(js_submenu_set_header)); mjs_set(mjs, submenu_obj, "show", ~0, MJS_MK_FN(js_submenu_show)); submenu->submenu = submenu_alloc(); - submenu->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_enable_queue(submenu->view_dispatcher); - view_dispatcher_add_view( - submenu->view_dispatcher, JsSubmenuViewSubmenu, submenu_get_view(submenu->submenu)); *object = submenu_obj; return submenu; } static void js_submenu_destroy(void* inst) { JsSubmenuInst* submenu = inst; - view_dispatcher_remove_view(submenu->view_dispatcher, JsSubmenuViewSubmenu); submenu_free(submenu->submenu); - view_dispatcher_free(submenu->view_dispatcher); free(submenu); } diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_0.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_0.png new file mode 100755 index 0000000000..7d42cb57db Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_0.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_1.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_1.png new file mode 100755 index 0000000000..25b4609c37 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_1.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_10.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_10.png new file mode 100755 index 0000000000..575df3b9f5 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_10.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_11.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_11.png new file mode 100755 index 0000000000..2cfc582ef9 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_11.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_12.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_12.png new file mode 100755 index 0000000000..4aa135cd6b Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_12.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_13.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_13.png new file mode 100755 index 0000000000..aae2827e85 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_13.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_14.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_14.png new file mode 100755 index 0000000000..a66867a326 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_14.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_15.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_15.png new file mode 100755 index 0000000000..7ec1216e30 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_15.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_16.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_16.png new file mode 100755 index 0000000000..2632103d6c Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_16.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_17.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_17.png new file mode 100755 index 0000000000..f50cd0b88d Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_17.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_18.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_18.png new file mode 100755 index 0000000000..b5a85de1df Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_18.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_19.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_19.png new file mode 100755 index 0000000000..d9a29def62 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_19.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_2.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_2.png new file mode 100755 index 0000000000..ca4bf322ba Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_2.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_20.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_20.png new file mode 100755 index 0000000000..fe95a716c1 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_20.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_21.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_21.png new file mode 100755 index 0000000000..6a40d4148f Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_21.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_22.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_22.png new file mode 100755 index 0000000000..67189811d8 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_22.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_23.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_23.png new file mode 100755 index 0000000000..b770f32088 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_23.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_24.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_24.png new file mode 100755 index 0000000000..4a899faf2f Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_24.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_25.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_25.png new file mode 100755 index 0000000000..c12a583f5a Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_25.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_26.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_26.png new file mode 100755 index 0000000000..f62f6495e4 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_26.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_27.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_27.png new file mode 100755 index 0000000000..37218c3961 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_27.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_28.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_28.png new file mode 100755 index 0000000000..a28511c916 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_28.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_29.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_29.png new file mode 100755 index 0000000000..f18f8798de Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_29.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_3.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_3.png new file mode 100755 index 0000000000..93e694375a Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_3.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_30.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_30.png new file mode 100755 index 0000000000..64cf585803 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_30.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_31.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_31.png new file mode 100755 index 0000000000..2502b3f21c Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_31.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_32.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_32.png new file mode 100755 index 0000000000..417419f858 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_32.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_33.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_33.png new file mode 100755 index 0000000000..5c79060755 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_33.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_34.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_34.png new file mode 100755 index 0000000000..26dfe53911 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_34.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_35.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_35.png new file mode 100755 index 0000000000..b6d5070573 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_35.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_36.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_36.png new file mode 100755 index 0000000000..7bd425e1d1 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_36.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_37.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_37.png new file mode 100755 index 0000000000..7edea62a16 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_37.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_38.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_38.png new file mode 100755 index 0000000000..7b51b6a34b Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_38.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_39.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_39.png new file mode 100755 index 0000000000..30b6bd67e1 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_39.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_4.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_4.png new file mode 100755 index 0000000000..ff0b1fb289 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_4.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_40.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_40.png new file mode 100755 index 0000000000..d413cf0ede Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_40.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_41.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_41.png new file mode 100755 index 0000000000..2770772652 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_41.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_42.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_42.png new file mode 100755 index 0000000000..baf3c7c79d Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_42.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_43.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_43.png new file mode 100755 index 0000000000..b4cb1179f3 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_43.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_44.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_44.png new file mode 100755 index 0000000000..09dfc28e8b Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_44.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_45.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_45.png new file mode 100755 index 0000000000..94b26fe061 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_45.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_46.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_46.png new file mode 100755 index 0000000000..28f47d714d Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_46.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_47.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_47.png new file mode 100755 index 0000000000..a9cc34ca20 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_47.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_48.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_48.png new file mode 100755 index 0000000000..cc9a89dad3 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_48.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_49.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_49.png new file mode 100755 index 0000000000..ef68cf8661 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_49.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_5.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_5.png new file mode 100755 index 0000000000..b0367a6032 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_5.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_50.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_50.png new file mode 100755 index 0000000000..a44a566c7b Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_50.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_51.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_51.png new file mode 100755 index 0000000000..ba00473ddd Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_51.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_52.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_52.png new file mode 100755 index 0000000000..8045749acb Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_52.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_53.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_53.png new file mode 100755 index 0000000000..18337cd63c Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_53.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_54.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_54.png new file mode 100755 index 0000000000..10be0ad16a Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_54.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_55.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_55.png new file mode 100755 index 0000000000..fd8269bb4d Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_55.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_56.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_56.png new file mode 100755 index 0000000000..300cbd9eca Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_56.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_6.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_6.png new file mode 100755 index 0000000000..56f37fbd89 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_6.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_7.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_7.png new file mode 100755 index 0000000000..0e4fb27a62 Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_7.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_8.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_8.png new file mode 100755 index 0000000000..641d06f39f Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_8.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_9.png b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_9.png new file mode 100755 index 0000000000..5bcf7e588c Binary files /dev/null and b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/frame_9.png differ diff --git a/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/meta.txt b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/meta.txt new file mode 100755 index 0000000000..4eeb913065 --- /dev/null +++ b/assets/dolphin/external/L3_Freedom_2_dolphins_128x64/meta.txt @@ -0,0 +1,23 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 20 +Active frames: 38 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 12 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 +Active cycles: 1 +Frame rate: 2 +Duration: 3600 +Active cooldown: 7 + +Bubble slots: 1 + +Slot: 0 +X: 52 +Y: 46 +Text: Thanks, man! +AlignH: Left +AlignV: Top +StartFrame: 37 +EndFrame: 40 \ No newline at end of file diff --git a/assets/dolphin/external/manifest.txt b/assets/dolphin/external/manifest.txt index 7be56ffbd9..b666316b88 100644 --- a/assets/dolphin/external/manifest.txt +++ b/assets/dolphin/external/manifest.txt @@ -183,6 +183,13 @@ Min level: 26 Max level: 30 Weight: 4 +Name: L3_Freedom_2_dolphins_128x64 +Min butthurt: 0 +Max butthurt: 14 +Min level: 28 +Max level: 30 +Weight: 5 + Name: L3_FlipperMustache_128x64 Min butthurt: 0 Max butthurt: 10 diff --git a/lib/one_wire/one_wire_slave.c b/lib/one_wire/one_wire_slave.c index 733b36e30e..6fff75214d 100644 --- a/lib/one_wire/one_wire_slave.c +++ b/lib/one_wire/one_wire_slave.c @@ -158,6 +158,8 @@ static inline bool onewire_slave_receive_and_process_command(OneWireSlave* bus) static inline bool onewire_slave_bus_start(OneWireSlave* bus) { FURI_CRITICAL_ENTER(); + + furi_hal_gpio_disable_int_callback(bus->gpio_pin); furi_hal_gpio_init(bus->gpio_pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); while(onewire_slave_receive_and_process_command(bus)) @@ -166,6 +168,8 @@ static inline bool onewire_slave_bus_start(OneWireSlave* bus) { const bool result = (bus->error == OneWireSlaveErrorNone); furi_hal_gpio_init(bus->gpio_pin, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_enable_int_callback(bus->gpio_pin); + FURI_CRITICAL_EXIT(); return result; diff --git a/lib/toolbox/name_generator.c b/lib/toolbox/name_generator.c index 5000bc7231..02cf5ab266 100644 --- a/lib/toolbox/name_generator.c +++ b/lib/toolbox/name_generator.c @@ -9,30 +9,15 @@ #include const char* const name_generator_left[] = { - "super", - "big", - "little", - "liquid", - "unknown", - "cheeky", - "tricky", - "sneaky", - "quick", - "quantum", - "kurwa", - "great", - "smart", - "mini", - "ultra", - "small", - "random", - "strange", + "super", "big", "little", "liquid", "unknown", "cheeky", "tricky", + "sneaky", "silly", "oh_my", "quick", "oh_no", "quantum", "kurwa", + "great", "smart", "mini", "ultra", "small", "random", "strange", }; const char* const name_generator_right[] = { - "maslina", "sus", "anomalija", "artefact", "bobr", "chomik", "sidorovich", - "stalker", "kit", "habar", "jezyk", "borov", "juzyk", "konserva", - "aptechka", "door", "zalaz", "breeky", "pingwin", "kot", + "maslina", "sus", "anomalija", "artefact", "bobr", "chomik", "sidorovich", + "stalker", "kit", "habar", "jezyk", "borov", "juzyk", "konserva", + "aptechka", "door", "zalaz", "breeky", "bunker", "pingwin", "kot", }; void name_generator_make_auto_datetime(