From d3f192ac36ffede5a17ae53711f81260e98b10c3 Mon Sep 17 00:00:00 2001 From: Mykhailo Shevchuk Date: Wed, 16 Oct 2024 02:24:43 +0300 Subject: [PATCH 01/10] Read Ultralight block by block --- .../mf_ultralight/mf_ultralight_poller.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c b/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c index 0e5ff0011..5cdf07f33 100644 --- a/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c +++ b/lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c @@ -505,16 +505,14 @@ static NfcCommand mf_ultralight_poller_handler_read_pages(MfUltralightPoller* in instance->error = mf_ultralight_poller_read_page(instance, start_page, &data); } - const uint8_t read_cnt = instance->data->type == MfUltralightTypeMfulC ? 1 : 4; if(instance->error == MfUltralightErrorNone) { - for(size_t i = 0; i < read_cnt; i++) { - if(start_page + i < instance->pages_total) { - FURI_LOG_D(TAG, "Read page %d success", start_page + i); - instance->data->page[start_page + i] = data.page[i]; - instance->pages_read++; - instance->data->pages_read = instance->pages_read; - } - } + if (start_page < instance->pages_total) { + FURI_LOG_D(TAG, "Read page %d success", start_page); + instance->data->page[start_page] = data.page[start_page]; + instance->pages_read++; + instance->data->pages_read = instance->pages_read; + } + if(instance->pages_read == instance->pages_total) { instance->state = MfUltralightPollerStateReadCounters; } From 2aff3bca733a87182466570557830df4f1252fc5 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:37:41 +0300 Subject: [PATCH 02/10] fix zero issues in princeton --- lib/subghz/protocols/princeton.c | 44 +++++++++++++++++++------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c index 25b34a6c7..040ed8378 100644 --- a/lib/subghz/protocols/princeton.c +++ b/lib/subghz/protocols/princeton.c @@ -141,10 +141,10 @@ static uint8_t subghz_protocol_princeton_get_btn_code(void) { case 0xC0: btn = 0x30; break; - case 0x03: + case 0xF3: btn = 0xC0; break; - case 0x0C: + case 0xFC: btn = 0xC0; break; @@ -170,16 +170,16 @@ static uint8_t subghz_protocol_princeton_get_btn_code(void) { break; // Second encoding type case 0x30: - btn = 0x03; + btn = 0xF3; break; case 0xC0: - btn = 0x03; + btn = 0xF3; break; - case 0x03: + case 0xF3: btn = 0x30; break; - case 0x0C: - btn = 0x03; + case 0xFC: + btn = 0xF3; break; default: @@ -204,15 +204,15 @@ static uint8_t subghz_protocol_princeton_get_btn_code(void) { break; // Second encoding type case 0x30: - btn = 0x0C; + btn = 0xFC; break; case 0xC0: - btn = 0x0C; + btn = 0xFC; break; - case 0x03: - btn = 0x0C; + case 0xF3: + btn = 0xFC; break; - case 0x0C: + case 0xFC: btn = 0x30; break; @@ -259,10 +259,12 @@ static bool // Reconstruction of the data // If we have 8bit button code move serial to left by 8 bits (and 4 if 4 bits) - if(instance->generic.btn == 0x30 || instance->generic.btn == 0xC0 || - instance->generic.btn == 0x03 || instance->generic.btn == 0x0C) { + if(instance->generic.btn == 0x30 || instance->generic.btn == 0xC0) { instance->generic.data = ((uint64_t)instance->generic.serial << 8 | (uint64_t)instance->generic.btn); + } else if(instance->generic.btn == 0xF3 || instance->generic.btn == 0xFC) { + instance->generic.data = + ((uint64_t)instance->generic.serial << 8 | (uint64_t)(instance->generic.btn & 0xF)); } else { instance->generic.data = ((uint64_t)instance->generic.serial << 4 | (uint64_t)instance->generic.btn); @@ -309,10 +311,14 @@ static void subghz_protocol_princeton_check_remote_controller(SubGhzBlockGeneric // Parse button modes for second encoding type (and serial is smaller) // Button code is 8bit and has fixed values of one of these // Exclude button code for each type from serial number before parsing - if((instance->data & 0xFF) == 0x30 || (instance->data & 0xFF) == 0xC0 || - (instance->data & 0xFF) == 0x03 || (instance->data & 0xFF) == 0x0C) { + if((instance->data & 0xFF) == 0x30 || (instance->data & 0xFF) == 0xC0) { + // Save serial and button code instance->serial = instance->data >> 8; instance->btn = instance->data & 0xFF; + } else if((instance->data & 0xFF) == 0x03 || (instance->data & 0xFF) == 0x0C) { + // Fix for button code 0x03 and 0x0C having zero at the beggining + instance->serial = instance->data >> 8; + instance->btn = (instance->data & 0xFF) | 0xF0; } else { instance->serial = instance->data >> 4; instance->btn = instance->data & 0xF; @@ -585,7 +591,7 @@ void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* out instance->generic.data, instance->generic.data_count_bit); if(instance->generic.btn == 0x30 || instance->generic.btn == 0xC0 || - instance->generic.btn == 0x03 || instance->generic.btn == 0x0C) { + instance->generic.btn == 0xF3 || instance->generic.btn == 0xFC) { furi_string_cat_printf( output, "%s %dbit\r\n" @@ -598,7 +604,9 @@ void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* out (uint32_t)(instance->generic.data & 0xFFFFFF), data_rev, instance->generic.serial, - instance->generic.btn, + (instance->generic.btn == 0xF3 || instance->generic.btn == 0xFC) ? + instance->generic.btn & 0xF : + instance->generic.btn, instance->te, instance->guard_time); } else { From 63d18901567bc15c3e21da13059cc810b92f3424 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:03:31 +0300 Subject: [PATCH 03/10] merge missing js backports of backports by Willy-JL p1 --- applications/system/js_app/js_thread.c | 6 ++-- .../system/js_app/modules/js_badusb.c | 2 +- .../js_app/modules/js_subghz/js_subghz.c | 5 ++++ .../system/js_app/modules/js_vgm/js_vgm.c | 8 +++--- .../system/js_app/modules/js_widget.c | 1 - .../system/js_app/types/badusb/index.d.ts | 18 ++++++++++-- applications/system/js_app/types/global.d.ts | 28 +++++++++++++++++++ .../system/js_app/types/gui/byte_input.ts | 14 ++++++++++ .../system/js_app/types/gui/text_input.d.ts | 2 ++ .../system/js_app/types/serial/index.d.ts | 21 ++++++++++++++ 10 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 applications/system/js_app/types/gui/byte_input.ts diff --git a/applications/system/js_app/js_thread.c b/applications/system/js_app/js_thread.c index 95cad84f6..c448945de 100644 --- a/applications/system/js_app/js_thread.c +++ b/applications/system/js_app/js_thread.c @@ -337,9 +337,9 @@ static int32_t js_thread(void* arg) { mjs_set(mjs, global, "toString", ~0, MJS_MK_FN(js_global_to_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_set(mjs, global, "parseInt", ~0, MJS_MK_FN(js_parse_int)); + mjs_set(mjs, global, "toUpperCase", ~0, MJS_MK_FN(js_to_upper_case)); + mjs_set(mjs, global, "toLowerCase", ~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 85a70b493..7a42d0a3a 100644 --- a/applications/system/js_app/modules/js_badusb.c +++ b/applications/system/js_app/modules/js_badusb.c @@ -104,7 +104,7 @@ static bool setup_parse_params( mjs_val_t pid_obj = mjs_get(mjs, arg, "pid", ~0); mjs_val_t mfr_obj = mjs_get(mjs, arg, "mfrName", ~0); mjs_val_t prod_obj = mjs_get(mjs, arg, "prodName", ~0); - mjs_val_t layout_obj = mjs_get(mjs, arg, "layout_path", ~0); + mjs_val_t layout_obj = mjs_get(mjs, arg, "layoutPath", ~0); if(mjs_is_number(vid_obj) && mjs_is_number(pid_obj)) { hid_cfg->vid = mjs_get_int32(mjs, vid_obj); 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 daa46e5e5..051566aec 100644 --- a/applications/system/js_app/modules/js_subghz/js_subghz.c +++ b/applications/system/js_app/modules/js_subghz/js_subghz.c @@ -282,6 +282,11 @@ static void js_subghz_transmit_file(struct mjs* mjs) { break; } + if(!subghz_devices_is_frequency_valid(js_subghz->radio_device, frequency)) { + mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Unsupported frequency"); + break; + } + if(!flipper_format_read_string(fff_file, "Preset", temp_str)) { mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Missing Preset"); break; diff --git a/applications/system/js_app/modules/js_vgm/js_vgm.c b/applications/system/js_app/modules/js_vgm/js_vgm.c index 2d7a56b6e..8d48d843f 100644 --- a/applications/system/js_app/modules/js_vgm/js_vgm.c +++ b/applications/system/js_app/modules/js_vgm/js_vgm.c @@ -144,10 +144,10 @@ static void js_vgm_destroy(void* inst) { } static const JsModuleDescriptor js_vgm_desc = { - name: "vgm", - create: js_vgm_create, - destroy: js_vgm_destroy, - api_interface: NULL, + "vgm", + js_vgm_create, + js_vgm_destroy, + NULL, }; static const FlipperAppPluginDescriptor plugin_descriptor = { diff --git a/applications/system/js_app/modules/js_widget.c b/applications/system/js_app/modules/js_widget.c index 64390abe7..1c0e98b7c 100644 --- a/applications/system/js_app/modules/js_widget.c +++ b/applications/system/js_app/modules/js_widget.c @@ -866,7 +866,6 @@ static void* js_widget_create(struct mjs* mjs, mjs_val_t* object, JsModules* mod widget->view_holder = view_holder_alloc(); view_holder_attach_to_gui(widget->view_holder, gui); view_holder_set_back_callback(widget->view_holder, widget_exit, widget); - view_holder_set_view(widget->view_holder, widget->view); *object = widget_obj; return widget; diff --git a/applications/system/js_app/types/badusb/index.d.ts b/applications/system/js_app/types/badusb/index.d.ts index 4b49dc991..872b8fe04 100644 --- a/applications/system/js_app/types/badusb/index.d.ts +++ b/applications/system/js_app/types/badusb/index.d.ts @@ -32,9 +32,12 @@ export type KeyCode = MainKey | ModifierKey | number; /** * @brief Initializes the module + * + * Automatically unlocks USB profile, so qFlipper connection will be interrupted. + * * @param settings USB device settings. Omit to select default parameters */ -export declare function setup(settings?: { vid: number, pid: number, mfrName?: string, prodName?: string, layout_path: string }): void; +export declare function setup(settings?: { vid: number, pid: number, mfrName?: string, prodName?: string, layoutPath: string }): void; /** * @brief Tells whether the virtual USB HID device has successfully connected @@ -83,10 +86,19 @@ export declare function println(string: string, delay?: number): void; /** * @brief Prints a string by Alt+Numpad method - works only on Windows! * @param string The string to print + * @param delay How many milliseconds to wait between key presses */ -export declare function altPrintln(string: string): void; +export declare function altPrint(string: string, delay?: number): void; /** - * @brief Releases usb, Optional, but allows to interchange with usbdisk + * @brief Prints a string by Alt+Numpad method - works only on Windows! + * Presses "Enter" after printing the string + * @param string The string to print + * @param delay How many milliseconds to wait between key presses + */ +export declare function altPrintln(string: string, delay?: number): void; + +/** + * @brief Releases usb, optional, but allows to interchange with usbdisk */ export declare function quit(): void; diff --git a/applications/system/js_app/types/global.d.ts b/applications/system/js_app/types/global.d.ts index ab1660cf6..b3e4aac33 100644 --- a/applications/system/js_app/types/global.d.ts +++ b/applications/system/js_app/types/global.d.ts @@ -18,6 +18,34 @@ declare function print(...args: any[]): void; */ declare function toString(value: number, base?: number): string; +/** + * @brief Converts a string to a number + * @param text The string to convert to a number + */ +declare function parseInt(text: string): number; + +/** + * @brief Transforms a string to upper case + * @param text The string to transforms to upper case + */ +declare function toUpperCase(text: string): string; + +/** + * @brief Transforms a string to lower case + * @param text The string to transforms to lower case + */ +declare function toLowerCase(text: string): string; + +/** + * @brief Path to the directory containing the current script + */ +declare const __dirpath: string; + +/** + * @brief Path to the current script file + */ +declare const __filepath: string; + /** * @brief Reads a JS value from a file * diff --git a/applications/system/js_app/types/gui/byte_input.ts b/applications/system/js_app/types/gui/byte_input.ts new file mode 100644 index 000000000..92bd4c5a8 --- /dev/null +++ b/applications/system/js_app/types/gui/byte_input.ts @@ -0,0 +1,14 @@ +import type { View, ViewFactory } from "."; +import type { Contract } from "../event_loop"; + +type Props = { + header: string, + length: number, + defaultData: Uint8Array | ArrayBuffer, +} +declare class ByteInput extends View { + input: Contract; +} +declare class ByteInputFactory extends ViewFactory { } +declare const factory: ByteInputFactory; +export = factory; diff --git a/applications/system/js_app/types/gui/text_input.d.ts b/applications/system/js_app/types/gui/text_input.d.ts index 96652b1d4..bdb5b4d4c 100644 --- a/applications/system/js_app/types/gui/text_input.d.ts +++ b/applications/system/js_app/types/gui/text_input.d.ts @@ -5,6 +5,8 @@ type Props = { header: string, minLength: number, maxLength: number, + defaultText: string, + defaultTextClear: boolean, } declare class TextInput extends View { input: Contract; diff --git a/applications/system/js_app/types/serial/index.d.ts b/applications/system/js_app/types/serial/index.d.ts index 1a7ed6397..680f9bd6e 100644 --- a/applications/system/js_app/types/serial/index.d.ts +++ b/applications/system/js_app/types/serial/index.d.ts @@ -1,5 +1,8 @@ /** * @brief Initializes the serial port + * + * Automatically disables Expansion module service to prevent interference. + * * @param port The port to initialize (`"lpuart"` or `"start"`) * @param baudRate */ @@ -42,6 +45,19 @@ export declare function read(length: number, timeout?: number): string | undefin */ export declare function readln(timeout?: number): string; +/** + * @brief Read any available amount of data from the serial port + * + * Can be useful to avoid starving your loop with small reads. + * + * @param timeout The number of time, in milliseconds, after which this function + * will give up and return nothing. If unset, the function will + * wait forever. + * @returns The received data interpreted as ASCII, or `undefined` if 0 bytes + * were read. + */ +export declare function readAny(timeout?: number): string | undefined; + /** * @brief Reads data from the serial port * @param length The number of bytes to read @@ -75,3 +91,8 @@ export declare function readBytes(length: number, timeout?: number): ArrayBuffer * patterns matched. */ export declare function expect(patterns: string | number[] | string[] | number[][], timeout?: number): number | undefined; + +/** + * @brief Deinitializes the serial port, allowing multiple initializations per script run + */ +export declare function end(): void; From f37799e0f45e546eda452211601ce5887678565d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:04:51 +0300 Subject: [PATCH 04/10] merge examples fixes [ci skip] by Willy-JL p2 --- .../examples/apps/Scripts/js_examples/adc.js | 42 --------- .../apps/Scripts/js_examples/badusb_demo.js | 86 +++++++++++-------- .../apps/Scripts/js_examples/blebeacon.js | 2 +- .../examples/apps/Scripts/js_examples/gui.js | 22 ++++- .../apps/Scripts/js_examples/keyboard.js | 23 ----- .../apps/Scripts/js_examples/stringutils.js | 8 +- 6 files changed, 77 insertions(+), 106 deletions(-) delete mode 100644 applications/system/js_app/examples/apps/Scripts/js_examples/adc.js delete mode 100644 applications/system/js_app/examples/apps/Scripts/js_examples/keyboard.js diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/adc.js b/applications/system/js_app/examples/apps/Scripts/js_examples/adc.js deleted file mode 100644 index 0506d348c..000000000 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/adc.js +++ /dev/null @@ -1,42 +0,0 @@ -// This is an example of how to use the analog pins (ADC) on the Flipper Zero. -// The example uses a reference voltage of 2048mV (2.048V), but you can also use 2500mV (2.5V). -// The example reads the values of the analog pins A7, A6, and A4 and prints them to the console. -// The example also checks if the value of A7 is twice the value of A6 and breaks the loop if it is. -// The example uses the analog pins A7, A6, and A4, but you can also use PC3, PC1, and PC0. - -let gpio = require("gpio"); - -// initialize pins A7, A6, A4 as analog (you can also use PC3, PC1, PC0) -gpio.init("PA7", "analog", "no"); // pin, mode, pull -gpio.init("PA6", "analog", "no"); // pin, mode, pull -gpio.init("PA4", "analog", "no"); // pin, mode, pull - -gpio.startAnalog(2048); // vRef = 2.048V (you can also use 2500 for a 2.5V reference voltage) - -while (true) { - let pa7_value = gpio.readAnalog("PA7"); - let pa6_value = gpio.readAnalog("PA6"); - let pa4_value = gpio.readAnalog("PA4"); - print("A7: " + to_string(pa7_value) + " A6: " + to_string(pa6_value) + " A4: " + to_string(pa4_value)); - delay(100); - if (pa7_value === pa6_value * 2) { - break; - } -} -print("A7 is twice A6!"); - -gpio.stopAnalog(); - -// possible analog pins https://docs.flipper.net/gpio-and-modules#miFsS -// "PA7" aka 2 -// "PA6" aka 3 -// "PA4" aka 4 -// "PC3" aka 7 -// "PC1" aka 15 -// "PC0" aka 16 - -// possible modes -// "analog" - -// possible pull -// "no" diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/badusb_demo.js b/applications/system/js_app/examples/apps/Scripts/js_examples/badusb_demo.js index 2bcf736c2..971c16c9e 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/badusb_demo.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/badusb_demo.js @@ -1,18 +1,10 @@ let badusb = require("badusb"); let notify = require("notification"); let flipper = require("flipper"); +let eventLoop = require("event_loop"); let gui = require("gui"); let dialog = require("gui/dialog"); - -// TODO: Add event loop from ofw -badusb.setup({ - vid: 0xAAAA, - pid: 0xBBBB, - mfrName: "Flipper", - prodName: "Zero", - layout_path: "/ext/badusb/assets/layouts/en-US.kl" -}); let views = { dialog: dialog.makeWith({ header: "BadUSB demo", @@ -21,37 +13,61 @@ let views = { }), }; -if (badusb.isConnected()) { - notify.blink("green", "short"); - print("USB is connected"); +badusb.setup({ + vid: 0xAAAA, + pid: 0xBBBB, + mfrName: "Flipper", + prodName: "Zero", + layoutPath: "/ext/badusb/assets/layouts/en-US.kl" +}); - badusb.println("Hello, world!"); +eventLoop.subscribe(views.dialog.input, function (_sub, button, eventLoop, gui) { + if (button !== "center") + return; - badusb.press("CTRL", "a"); - badusb.press("CTRL", "c"); - badusb.press("DOWN"); - delay(1000); - badusb.press("CTRL", "v"); - delay(1000); - badusb.press("CTRL", "v"); + gui.viewDispatcher.sendTo("back"); - badusb.println("1234", 200); + if (badusb.isConnected()) { + notify.blink("green", "short"); + print("USB is connected"); - badusb.println("Flipper Model: " + flipper.getModel()); - badusb.println("Flipper Name: " + flipper.getName()); - badusb.println("Battery level: " + toString(flipper.getBatteryCharge()) + "%"); + badusb.println("Hello, world!"); - // Alt+Numpad method works only on Windows!!! - badusb.altPrintln("This was printed with Alt+Numpad method!"); + badusb.press("CTRL", "a"); + badusb.press("CTRL", "c"); + badusb.press("DOWN"); + delay(1000); + badusb.press("CTRL", "v"); + delay(1000); + badusb.press("CTRL", "v"); - // There's also badusb.print() and badusb.altPrint() - // which don't add the return at the end + badusb.println("1234", 200); - notify.success(); -} else { - print("USB not connected"); - notify.error(); -} + badusb.println("Flipper Model: " + flipper.getModel()); + badusb.println("Flipper Name: " + flipper.getName()); + badusb.println("Battery level: " + toString(flipper.getBatteryCharge()) + "%"); -// Optional, but allows to interchange with usbdisk -badusb.quit(); \ No newline at end of file + // 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"); + notify.error(); + } + + // Optional, but allows to interchange with usbdisk + badusb.quit(); + + eventLoop.stop(); +}, eventLoop, gui); + +eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _item, eventLoop) { + eventLoop.stop(); +}, eventLoop); + +gui.viewDispatcher.switchTo(views.dialog); +eventLoop.run(); diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/blebeacon.js b/applications/system/js_app/examples/apps/Scripts/js_examples/blebeacon.js index 53983a745..9a30ad151 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/blebeacon.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/blebeacon.js @@ -45,7 +45,7 @@ function sendRandomModelAdvertisement() { blebeacon.start(); - print("Sent data for model ID " + to_string(model)); + print("Sent data for model ID " + toString(model)); currentIndex = (currentIndex + 1) % watchValues.length; diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js b/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js index dd80b5bc4..7121ab1fe 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js @@ -5,6 +5,7 @@ let loadingView = require("gui/loading"); let submenuView = require("gui/submenu"); let emptyView = require("gui/empty_screen"); let textInputView = require("gui/text_input"); +let byteInputView = require("gui/byte_input"); let textBoxView = require("gui/text_box"); let dialogView = require("gui/dialog"); @@ -20,6 +21,11 @@ let views = { helloDialog: dialogView.makeWith({ center: "Hi Flipper! :)", }), + bytekb: byteInputView.makeWith({ + header: "Look ma, I'm a header text!", + length: 8, + defaultData: Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]), + }), longText: textBoxView.makeWith({ text: "This is a very long string that demonstrates the TextBox view. Use the D-Pad to scroll backwards and forwards.\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse rhoncus est malesuada quam egestas ultrices. Maecenas non eros a nulla eleifend vulputate et ut risus. Quisque in mauris mattis, venenatis risus eget, aliquam diam. Fusce pretium feugiat mauris, ut faucibus ex volutpat in. Phasellus volutpat ex sed gravida consectetur. Aliquam sed lectus feugiat, tristique lectus et, bibendum lacus. Ut sit amet augue eu sapien elementum aliquam quis vitae tortor. Vestibulum quis commodo odio. In elementum fermentum massa, eu pellentesque nibh cursus at. Integer eleifend lacus nec purus elementum sodales. Nulla elementum neque urna, non vulputate massa semper sed. Fusce ut nisi vitae dui blandit congue pretium vitae turpis.", }), @@ -29,6 +35,7 @@ let views = { "Hourglass screen", "Empty screen", "Text input & Dialog", + "Byte input", "Text box", "Exit app", ], @@ -49,8 +56,10 @@ eventLoop.subscribe(views.demos.chosen, function (_sub, index, gui, eventLoop, v } else if (index === 2) { gui.viewDispatcher.switchTo(views.keyboard); } else if (index === 3) { - gui.viewDispatcher.switchTo(views.longText); + gui.viewDispatcher.switchTo(views.bytekb); } else if (index === 4) { + gui.viewDispatcher.switchTo(views.longText); + } else if (index === 5) { eventLoop.stop(); } }, gui, eventLoop, views); @@ -67,6 +76,17 @@ eventLoop.subscribe(views.helloDialog.input, function (_sub, button, gui, views) gui.viewDispatcher.switchTo(views.demos); }, gui, views); +// show data after byte input +eventLoop.subscribe(views.bytekb.input, function (_sub, data, gui, views) { + let data_view = Uint8Array(data); + let text = "0x"; + for (let i = 0; i < data_view.length; i++) { + text += toString(data_view[i], 16); + } + views.helloDialog.set("text", "You typed " + text + "! :)"); + gui.viewDispatcher.switchTo(views.helloDialog); +}, gui, views); + // go to the demo chooser screen when the back key is pressed eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _, gui, views) { gui.viewDispatcher.switchTo(views.demos); diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/keyboard.js b/applications/system/js_app/examples/apps/Scripts/js_examples/keyboard.js deleted file mode 100644 index 2b01418de..000000000 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/keyboard.js +++ /dev/null @@ -1,23 +0,0 @@ -let keyboard = require("keyboard"); - -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 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/js_examples/stringutils.js b/applications/system/js_app/examples/apps/Scripts/js_examples/stringutils.js index 51781328d..c1f4d447a 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/stringutils.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/stringutils.js @@ -1,6 +1,6 @@ let sampleText = "Hello, World!"; -let lengthOfText = "Length of text: " + to_string(sampleText.length); +let lengthOfText = "Length of text: " + toString(sampleText.length); print(lengthOfText); let start = 7; @@ -9,11 +9,11 @@ let substringResult = sampleText.slice(start, end); print(substringResult); let searchStr = "World"; -let result2 = to_string(sampleText.indexOf(searchStr)); +let result2 = toString(sampleText.indexOf(searchStr)); print(result2); -let upperCaseText = "Text in upper case: " + to_upper_case(sampleText); +let upperCaseText = "Text in upper case: " + toUpperCase(sampleText); print(upperCaseText); -let lowerCaseText = "Text in lower case: " + to_lower_case(sampleText); +let lowerCaseText = "Text in lower case: " + toLowerCase(sampleText); print(lowerCaseText); From cd46d8ca07921d41b629c0cc284b37fc4a2fc5a3 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:09:51 +0300 Subject: [PATCH 05/10] more js stuff https://github.com/Next-Flip/Momentum-Firmware/commits/js-backport-of-backport/ --- .../examples/apps/Scripts/js_examples/path.js | 2 +- .../apps/Scripts/js_examples/storage.js | 42 +++++++------------ applications/system/js_app/types/global.d.ts | 21 ++++++++++ .../gui/{byte_input.ts => byte_input.d.ts} | 0 4 files changed, 36 insertions(+), 29 deletions(-) rename applications/system/js_app/types/gui/{byte_input.ts => byte_input.d.ts} (100%) diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/path.js b/applications/system/js_app/examples/apps/Scripts/js_examples/path.js index 0381150d2..9d3159d9f 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/path.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/path.js @@ -2,7 +2,7 @@ let storage = require("storage"); print("script has __dirpath of" + __dirpath); print("script has __filepath of" + __filepath); -if (storage.exists(__dirpath + "/math.js")) { +if (storage.fileExists(__dirpath + "/math.js")) { print("math.js exist here."); } else { print("math.js does not exist here."); diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/storage.js b/applications/system/js_app/examples/apps/Scripts/js_examples/storage.js index 9d873af97..5f273c628 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/storage.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/storage.js @@ -1,43 +1,29 @@ let storage = require("storage"); let path = "/ext/storage.test"; -function arraybuf_to_string(arraybuf) { - let string = ""; - let data_view = Uint8Array(arraybuf); - for (let i = 0; i < data_view.length; i++) { - string += chr(data_view[i]); - } - return string; -} - -print("File exists:", storage.exists(path)); +print("File exists:", storage.fileExists(path)); print("Writing..."); -// write(path, data, offset) -// If offset is specified, the file is not cleared, content is kept and data is written at specified offset -// Takes both strings and array buffers -storage.write(path, "Hello "); +let file = storage.openFile(path, "w", "create_always"); +file.write("Hello "); +file.close(); -print("File exists:", storage.exists(path)); +print("File exists:", storage.fileExists(path)); -// Append will create the file even if it doesnt exist! -// Takes both strings and array buffers -storage.append(path, "World!"); +file = storage.openFile(path, "w", "open_append"); +file.write("World!"); +file.close(); print("Reading..."); -// read(path, size, offset) -// If no size specified, total filesize is used -// If offset is specified, size is capped at (filesize - offset) -let data = storage.read(path); -// read returns an array buffer, to allow proper usage of raw binary data -print(arraybuf_to_string(data)); +file = storage.openFile(path, "r", "open_existing"); +let text = file.read("ascii", 128); +file.close(); +print(text); print("Removing...") storage.remove(path); print("Done") -// There's also: -// storage.copy(old_path, new_path); -// storage.move(old_path, new_path); -// storage.mkdir(path); \ No newline at end of file +// You don't need to close the file after each operation, this is just to show some different ways to use +// There's also many more functions and options, check types docs in firmware repo \ No newline at end of file diff --git a/applications/system/js_app/types/global.d.ts b/applications/system/js_app/types/global.d.ts index b3e4aac33..01a8fbcef 100644 --- a/applications/system/js_app/types/global.d.ts +++ b/applications/system/js_app/types/global.d.ts @@ -56,6 +56,15 @@ declare const __filepath: string; */ declare function load(path: string): any; +/** + * @brief Return 1-byte string whose ASCII code is the integer `n` + * + * If `n` is not numeric or outside of `0-255` range, `null` is returned + * + * @param n The ASCII code to convert to string + */ +declare function chr(n: number): string | null; + /** * @brief mJS Foreign Pointer type * @@ -189,6 +198,18 @@ declare class String { * See `charCodeAt` */ at(index: number): number; + /** + * @brief Return index of first occurence of substr within the string or `-1` if not found + * @param substr The string to search for + * @param fromIndex The index to start searching from + */ + indexOf(substr: string, fromIndex?: number): number; + /** + * @brief Return a substring between two indices + * @param start The index to start substring at + * @param end The index to end substring at + */ + slice(start: number, end?: number): string; } declare class Boolean { } diff --git a/applications/system/js_app/types/gui/byte_input.ts b/applications/system/js_app/types/gui/byte_input.d.ts similarity index 100% rename from applications/system/js_app/types/gui/byte_input.ts rename to applications/system/js_app/types/gui/byte_input.d.ts From 38fb892cbbe412f67ff35acd2d9391ef5951be89 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:07:58 +0300 Subject: [PATCH 06/10] merge js upds 1 --- .../examples/apps/Scripts/js_examples/gui.js | 23 ++++-- .../apps/Scripts/js_examples/interactive.js | 77 +++++++++++++++++++ .../examples/apps/Scripts/js_examples/load.js | 2 +- 3 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 applications/system/js_app/examples/apps/Scripts/js_examples/interactive.js diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js b/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js index 7121ab1fe..7e61e04ed 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/gui.js @@ -8,6 +8,7 @@ let textInputView = require("gui/text_input"); let byteInputView = require("gui/byte_input"); let textBoxView = require("gui/text_box"); let dialogView = require("gui/dialog"); +let flipper = require("flipper"); // declare view instances let views = { @@ -15,16 +16,18 @@ let views = { empty: emptyView.make(), keyboard: textInputView.makeWith({ header: "Enter your name", + defaultText: flipper.getName(), + defaultTextClear: true, + // Props for makeWith() are passed in reverse order, so maxLength must be after defaultText minLength: 0, maxLength: 32, }), - helloDialog: dialogView.makeWith({ - center: "Hi Flipper! :)", - }), + helloDialog: dialogView.make(), bytekb: byteInputView.makeWith({ header: "Look ma, I'm a header text!", - length: 8, defaultData: Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]), + // Props for makeWith() are passed in reverse order, so length must be after defaultData + length: 8, }), longText: textBoxView.makeWith({ text: "This is a very long string that demonstrates the TextBox view. Use the D-Pad to scroll backwards and forwards.\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse rhoncus est malesuada quam egestas ultrices. Maecenas non eros a nulla eleifend vulputate et ut risus. Quisque in mauris mattis, venenatis risus eget, aliquam diam. Fusce pretium feugiat mauris, ut faucibus ex volutpat in. Phasellus volutpat ex sed gravida consectetur. Aliquam sed lectus feugiat, tristique lectus et, bibendum lacus. Ut sit amet augue eu sapien elementum aliquam quis vitae tortor. Vestibulum quis commodo odio. In elementum fermentum massa, eu pellentesque nibh cursus at. Integer eleifend lacus nec purus elementum sodales. Nulla elementum neque urna, non vulputate massa semper sed. Fusce ut nisi vitae dui blandit congue pretium vitae turpis.", @@ -67,6 +70,7 @@ eventLoop.subscribe(views.demos.chosen, function (_sub, index, gui, eventLoop, v // say hi after keyboard input eventLoop.subscribe(views.keyboard.input, function (_sub, name, gui, views) { views.helloDialog.set("text", "Hi " + name + "! :)"); + views.helloDialog.set("center", "Hi Flipper! :)"); gui.viewDispatcher.switchTo(views.helloDialog); }, gui, views); @@ -83,14 +87,19 @@ eventLoop.subscribe(views.bytekb.input, function (_sub, data, gui, views) { for (let i = 0; i < data_view.length; i++) { text += toString(data_view[i], 16); } - views.helloDialog.set("text", "You typed " + text + "! :)"); + views.helloDialog.set("text", "You typed:\n" + text); + views.helloDialog.set("center", "Cool!"); gui.viewDispatcher.switchTo(views.helloDialog); }, gui, views); // go to the demo chooser screen when the back key is pressed -eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _, gui, views) { +eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _, gui, views, eventLoop) { + if (gui.viewDispatcher.currentView === views.demos) { + eventLoop.stop(); + return; + } gui.viewDispatcher.switchTo(views.demos); -}, gui, views); +}, gui, views, eventLoop); // run UI gui.viewDispatcher.switchTo(views.demos); diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/interactive.js b/applications/system/js_app/examples/apps/Scripts/js_examples/interactive.js new file mode 100644 index 000000000..63db6c5e0 --- /dev/null +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/interactive.js @@ -0,0 +1,77 @@ +let eventLoop = require("event_loop"); +let gui = require("gui"); +let dialog = require("gui/dialog"); +let textInput = require("gui/text_input"); +let loading = require("gui/loading"); +let storage = require("storage"); + +// No eval() or exec() so need to run code from file, and filename must be unique +storage.makeDirectory("/ext/.tmp"); +storage.makeDirectory("/ext/.tmp/js"); +storage.rmrf("/ext/.tmp/js/repl") +storage.makeDirectory("/ext/.tmp/js/repl") +let ctx = { + tmp_template: "/ext/.tmp/js/repl/", + tmp_number: 0, +}; + +let views = { + dialog: dialog.makeWith({ + header: "Interactive Console", + text: "Press OK to Start", + center: "Run Some JS" + }), + textInput: textInput.makeWith({ + header: "Type JavaScript Code:", + defaultText: "2+2", + defaultTextClear: true, + // Props for makeWith() are passed in reverse order, so maxLength must be after defaultText + minLength: 0, + maxLength: 256, + }), + loading: loading.make(), +}; + +eventLoop.subscribe(views.dialog.input, function (_sub, button, gui, views) { + if (button === "center") { + gui.viewDispatcher.switchTo(views.textInput); + } +}, gui, views); + +eventLoop.subscribe(views.textInput.input, function (_sub, text, gui, views, ctx) { + gui.viewDispatcher.switchTo(views.loading); + + let path = ctx.tmp_template + toString(ctx.tmp_number++); + let file = storage.openFile(path, "w", "create_always"); + file.write("({run:function(){return " + text + ";},})"); + file.close(); + + // Hide GUI before running, we want to see console and avoid deadlock if code fails + gui.viewDispatcher.sendTo("back"); + let result = load(path).run(); + storage.remove(path); + gui.viewDispatcher.sendTo("front"); + + // Must convert to string explicitly + if (typeof result === "number") { + result = toString(result); + } else if (typeof result === "undefined") { + result = "undefined"; + } else if (typeof result === "boolean") { + result = result ? "true" : "false"; + } else if (typeof result === "object") { + result = JSON.stringify(result); + } + + views.dialog.set("header", "JS Returned:"); + views.dialog.set("text", result); + gui.viewDispatcher.switchTo(views.dialog); + views.textInput.set("defaultText", text); +}, gui, views, ctx); + +eventLoop.subscribe(gui.viewDispatcher.navigation, function (_sub, _, eventLoop) { + eventLoop.stop(); +}, eventLoop); + +gui.viewDispatcher.switchTo(views.dialog); +eventLoop.run(); diff --git a/applications/system/js_app/examples/apps/Scripts/js_examples/load.js b/applications/system/js_app/examples/apps/Scripts/js_examples/load.js index 813619741..3b8f2d8fd 100644 --- a/applications/system/js_app/examples/apps/Scripts/js_examples/load.js +++ b/applications/system/js_app/examples/apps/Scripts/js_examples/load.js @@ -1,3 +1,3 @@ -let math = load("/ext/apps/Scripts/load_api.js"); +let math = load(__dirpath + "/load_api.js"); let result = math.add(5, 10); print(result); From 521b793011fdb6654685e592133fa49461b48a5d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:09:02 +0300 Subject: [PATCH 07/10] merge js 2 --- .../system/js_app/modules/js_gui/byte_input.c | 24 +++++++++++---- .../system/js_app/modules/js_gui/js_gui.c | 5 +++- .../system/js_app/modules/js_gui/text_input.c | 29 ++++++++++++++++--- .../system/js_app/types/gui/index.d.ts | 4 +++ 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/applications/system/js_app/modules/js_gui/byte_input.c b/applications/system/js_app/modules/js_gui/byte_input.c index 2e4096b28..5c8844d22 100644 --- a/applications/system/js_app/modules/js_gui/byte_input.c +++ b/applications/system/js_app/modules/js_gui/byte_input.c @@ -40,6 +40,13 @@ static bool UNUSED(input); context->buffer_size = (size_t)(value.number); context->buffer = realloc(context->buffer, context->buffer_size); //-V701 + byte_input_set_result_callback( + input, + (ByteInputCallback)input_callback, + NULL, + context, + context->buffer, + context->buffer_size); return true; } @@ -50,11 +57,12 @@ static bool default_data_assign( JsByteKbContext* context) { UNUSED(mjs); - if(mjs_is_data_view(value.array)) { - value.array = mjs_dataview_get_buf(mjs, value.array); + mjs_val_t array_buf = value.array; + if(mjs_is_data_view(array_buf)) { + array_buf = mjs_dataview_get_buf(mjs, array_buf); } size_t default_data_len = 0; - char* default_data = mjs_array_buf_get_ptr(mjs, value.array, &default_data_len); + char* default_data = mjs_array_buf_get_ptr(mjs, array_buf, &default_data_len); memcpy( context->buffer, (uint8_t*)default_data, @@ -71,7 +79,6 @@ static bool default_data_assign( } static JsByteKbContext* ctx_make(struct mjs* mjs, ByteInput* input, mjs_val_t view_obj) { - UNUSED(input); JsByteKbContext* context = malloc(sizeof(JsByteKbContext)); *context = (JsByteKbContext){ .buffer_size = DEFAULT_BUF_SZ, @@ -90,8 +97,13 @@ static JsByteKbContext* ctx_make(struct mjs* mjs, ByteInput* input, mjs_val_t vi .transformer_context = context, }, }; - UNUSED(mjs); - UNUSED(view_obj); + byte_input_set_result_callback( + input, + (ByteInputCallback)input_callback, + NULL, + context, + context->buffer, + context->buffer_size); mjs_set(mjs, view_obj, "input", ~0, mjs_mk_foreign(mjs, &context->contract)); return context; } diff --git a/applications/system/js_app/modules/js_gui/js_gui.c b/applications/system/js_app/modules/js_gui/js_gui.c index 011f404e9..4bd4ccc31 100644 --- a/applications/system/js_app/modules/js_gui/js_gui.c +++ b/applications/system/js_app/modules/js_gui/js_gui.c @@ -101,8 +101,10 @@ static void js_gui_vd_switch_to(struct mjs* mjs) { mjs_val_t view; JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_OBJ(&view)); JsGuiViewData* view_data = JS_GET_INST(mjs, view); - JsGui* module = JS_GET_CONTEXT(mjs); + mjs_val_t vd_obj = mjs_get_this(mjs); + JsGui* module = JS_GET_INST(mjs, vd_obj); view_dispatcher_switch_to_view(module->dispatcher, (uint32_t)view_data->id); + mjs_set(mjs, vd_obj, "currentView", ~0, view); } static void* js_gui_create(struct mjs* mjs, mjs_val_t* object, JsModules* modules) { @@ -154,6 +156,7 @@ static void* js_gui_create(struct mjs* mjs, mjs_val_t* object, JsModules* module JS_FIELD("switchTo", MJS_MK_FN(js_gui_vd_switch_to)); JS_FIELD("custom", mjs_mk_foreign(mjs, &module->custom_contract)); JS_FIELD("navigation", mjs_mk_foreign(mjs, &module->navigation_contract)); + JS_FIELD("currentView", MJS_NULL); } // create API object diff --git a/applications/system/js_app/modules/js_gui/text_input.c b/applications/system/js_app/modules/js_gui/text_input.c index a43147e43..f68978e2d 100644 --- a/applications/system/js_app/modules/js_gui/text_input.c +++ b/applications/system/js_app/modules/js_gui/text_input.c @@ -9,6 +9,7 @@ typedef struct { char* buffer; size_t buffer_size; FuriString* header; + bool default_text_clear; FuriSemaphore* input_semaphore; JsEventLoopContract contract; } JsKbdContext; @@ -51,6 +52,13 @@ static bool max_len_assign( UNUSED(input); context->buffer_size = (size_t)(value.number + 1); context->buffer = realloc(context->buffer, context->buffer_size); //-V701 + text_input_set_result_callback( + input, + (TextInputCallback)input_callback, + context, + context->buffer, + context->buffer_size, + context->default_text_clear); return true; } @@ -64,6 +72,13 @@ static bool default_text_assign( if(value.string) { strlcpy(context->buffer, value.string, context->buffer_size); + text_input_set_result_callback( + input, + (TextInputCallback)input_callback, + context, + context->buffer, + context->buffer_size, + context->default_text_clear); } return true; } @@ -75,23 +90,24 @@ static bool default_text_clear_assign( JsKbdContext* context) { UNUSED(mjs); + context->default_text_clear = value.boolean; text_input_set_result_callback( input, (TextInputCallback)input_callback, context, context->buffer, context->buffer_size, - value.boolean); + context->default_text_clear); return true; } static JsKbdContext* ctx_make(struct mjs* mjs, TextInput* input, mjs_val_t view_obj) { - UNUSED(input); JsKbdContext* context = malloc(sizeof(JsKbdContext)); *context = (JsKbdContext){ .buffer_size = DEFAULT_BUF_SZ, .buffer = malloc(DEFAULT_BUF_SZ), .header = furi_string_alloc(), + .default_text_clear = false, .input_semaphore = furi_semaphore_alloc(1, 0), }; context->contract = (JsEventLoopContract){ @@ -105,8 +121,13 @@ static JsKbdContext* ctx_make(struct mjs* mjs, TextInput* input, mjs_val_t view_ .transformer_context = context, }, }; - UNUSED(mjs); - UNUSED(view_obj); + text_input_set_result_callback( + input, + (TextInputCallback)input_callback, + context, + context->buffer, + context->buffer_size, + context->default_text_clear); mjs_set(mjs, view_obj, "input", ~0, mjs_mk_foreign(mjs, &context->contract)); return context; } diff --git a/applications/system/js_app/types/gui/index.d.ts b/applications/system/js_app/types/gui/index.d.ts index 3f95ab780..85f191059 100644 --- a/applications/system/js_app/types/gui/index.d.ts +++ b/applications/system/js_app/types/gui/index.d.ts @@ -20,6 +20,10 @@ declare class ViewDispatcher { * Event source for navigation events (back key presses) */ navigation: Contract; + /** + * View object currently shown + */ + currentView: View; /** * Sends a number to the custom event handler * @param event number to send From 1df18417fab342f0c80799913d6abc3889ef01a5 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 18:23:54 +0300 Subject: [PATCH 08/10] upd changelog --- CHANGELOG.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad4d3d04a..214172c47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,25 +7,38 @@ - Fix buttons logic, fix crash - Protocol improvements: - Princeton support for second button encoding type (8bit) - - GangQi fix serial check + - GangQi fix serial check and remove broken check from UI - Hollarm add more button codes (thanks to @mishamyte for captures) - Misc: - Add extra settings to disable GPIO pins control used for external modules amplifiers and/or LEDs (in radio settings menu with debug ON) - NFC: - OFW PR 3822: MIFARE Classic Key Recovery Improvements (by @noproto) - - OFW PR 3918: NFC Some api adjustments (by @RebornedBrain) - OFW PR 3930: NFC Emulation freeze (by @RebornedBrain) - OFW PR 3885: Add API to enforce ISO15693 mode (by @aaronjamt) + - OFW: iso14443_4a improvements (by @RebornedBrain) - OFW: Plantain parser improvements (by @assasinfil) - OFW: Moscow social card parser (by @assasinfil) + - OFW: NFC: H World Hotel Chain Room Key Parser + - New keys in system dict - Infrared: - Add LEDs universal remote (DB by @amec0e) - Update universal remote assets (by @amec0e | PR #813 #816) -* OFW: FuriHal, drivers: rework gauge initialization routine +* JS: Backporting custom features - WIP (by @xMasterX and @Willy-JL) +* OFW: FuriHal, drivers: rework gauge initialization routine -> **Downgrade to older releases will break battery UI percent indicator, upgrade to this or newer version to restore** +* OFW: JS modules -> **Breaking API change** +* OFW: heap: increased size -> **More free RAM!!** +* OFW: CLI improvements, part I -> **Breaking API change** * OFW: New layout for BadUSB (es-LA) +* OFW: Require PIN on boot * Apps: **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev) ## Other changes -* OFW PR 3931: Split BadUSB into BadUSB and BadBLE (by @Astrrra) +* OFW: Small fixes in the wifi devboard docs +* OFW: BadUSB - Improve ChromeOS and GNOME demo scripts +* OFW: Small JS fixes +* OFW: Canvas: extended icon draw. +* OFW: Fixes Mouse Clicker Should have a "0" value setting for "as fast as possible" +* OFW: Wi-Fi Devboard documentation rework +* OFW: Furi: A Lot of Fixes * OFW PR 3933: furi_hal_random: Wait for ready state and no errors before sampling (by @n1kolasM) * OFW: nfc/clipper: Update BART station codes * OFW: FuriThread: Improve state callbacks From 4e5abdadffdd93e1ccbc5089a9baaaad835ce469 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:35:52 +0300 Subject: [PATCH 09/10] fix cli breaking web flipper lab, remove color tags --- applications/services/cli/cli.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/applications/services/cli/cli.c b/applications/services/cli/cli.c index 0bf2ce4d1..bb48b1efa 100644 --- a/applications/services/cli/cli.c +++ b/applications/services/cli/cli.c @@ -109,8 +109,7 @@ void cli_print_usage(const char* cmd, const char* usage, const char* arg) { } void cli_motd(void) { - printf(ANSI_FLIPPER_BRAND_ORANGE - "\r\n" + printf("\r\n" " _.-------.._ -,\r\n" " .-\"```\"--..,,_/ /`-, -, \\ \r\n" " .:\" /:/ /'\\ \\ ,_..., `. | |\r\n" @@ -124,11 +123,12 @@ void cli_motd(void) { " _L_ _ ___ ___ ___ ___ ____--\"`___ _ ___\r\n" "| __|| | |_ _|| _ \\| _ \\| __|| _ \\ / __|| | |_ _|\r\n" "| _| | |__ | | | _/| _/| _| | / | (__ | |__ | |\r\n" - "|_| |____||___||_| |_| |___||_|_\\ \\___||____||___|\r\n" ANSI_RESET - "\r\n" ANSI_FG_BR_WHITE "Welcome to " ANSI_FLIPPER_BRAND_ORANGE - "Flipper Zero" ANSI_FG_BR_WHITE " Command Line Interface!\r\n" + "|_| |____||___||_| |_| |___||_|_\\ \\___||____||___|\r\n" + "\r\n" + "Welcome to Flipper Zero Command Line Interface!\r\n" "Read the manual: https://docs.flipper.net/development/cli\r\n" - "Run `help` or `?` to list available commands\r\n" ANSI_RESET "\r\n"); + "Run `help` or `?` to list available commands\r\n" + "\r\n"); const Version* firmware_version = furi_hal_version_get_firmware_version(); if(firmware_version) { From 9c20bdc287f1dce8168efa41d05fa74f1dd5ab6d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:55:25 +0300 Subject: [PATCH 10/10] upd changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 214172c47..65721b6cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Misc: - Add extra settings to disable GPIO pins control used for external modules amplifiers and/or LEDs (in radio settings menu with debug ON) - NFC: + - Read Ultralight block by block (by @mishamyte | PR #825) - OFW PR 3822: MIFARE Classic Key Recovery Improvements (by @noproto) - OFW PR 3930: NFC Emulation freeze (by @RebornedBrain) - OFW PR 3885: Add API to enforce ISO15693 mode (by @aaronjamt) @@ -19,6 +20,7 @@ - OFW: Plantain parser improvements (by @assasinfil) - OFW: Moscow social card parser (by @assasinfil) - OFW: NFC: H World Hotel Chain Room Key Parser + - OFW: NFC Parser for Tianjin Railway Transit - New keys in system dict - Infrared: - Add LEDs universal remote (DB by @amec0e) @@ -27,7 +29,7 @@ * OFW: FuriHal, drivers: rework gauge initialization routine -> **Downgrade to older releases will break battery UI percent indicator, upgrade to this or newer version to restore** * OFW: JS modules -> **Breaking API change** * OFW: heap: increased size -> **More free RAM!!** -* OFW: CLI improvements, part I -> **Breaking API change** +* OFW: CLI improvements, part I -> **Breaking API change** -> + fix web flipper lab * OFW: New layout for BadUSB (es-LA) * OFW: Require PIN on boot * Apps: **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev)