mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-21 20:42:15 -07:00
Merge remote-tracking branch 'mntm/dev' into kiisu-mntm
This commit is contained in:
+14
-2
@@ -1,10 +1,21 @@
|
||||
### Added:
|
||||
- Apps:
|
||||
- Games: Geometry Flip (by @goosedev72-projects)
|
||||
- GPIO: [KT0803] FM Transmitter (by @goosedev72-projects)
|
||||
- GPIO/ESP: [ESP32] Ghost ESP (by @jaylikesbunda)
|
||||
- GPIO/FlipBoard:
|
||||
- FlipBoard Blinky (by @jamisonderek)
|
||||
- FlipBoard Keyboard (by @jamisonderek)
|
||||
- FlipBoard Signal (by @jamisonderek)
|
||||
- FlipBoard Simon (by @jamisonderek)
|
||||
- GPIO/FlipperHTTP: Free Roam (by @jblanked)
|
||||
- GPIO/GPS: [NMEA] Nearby Files (by @Stichoza)
|
||||
- Media: Video Player (by @LTVA1)
|
||||
- NFC: NFC-Eink (by @RebornedBrain)
|
||||
- RFID: Simultaneous UHF RFID Reader (by @haffnerriley)
|
||||
- Sub-GHz: Sub Analyzer (by @RocketGod-git)
|
||||
- Sub-GHz:
|
||||
- Chief Cooker (by @denr01)
|
||||
- Sub Analyzer (by @RocketGod-git)
|
||||
- SubGHz:
|
||||
- UL: Roger (static 28 bit) with add manually support (by @xMasterX & @mishamyte)
|
||||
- UL: V2 Phoenix full support (button switch, add manually, counter decrypt/encrypt) (by @xMasterX & @RocketGod-git, original code by @Skorpionm)
|
||||
@@ -36,7 +47,7 @@
|
||||
- Metroflip: Fix unsupported card crash, RENFE Suma 10 support, GEG Connect AID added, Top Up log parsing and animations, 16 new rail lines, support for parsing area codes, saving function for Suica/Japan Rail IC, bugfixes (by @luu176)
|
||||
- NFC Maker: Support making empty/blank NDEF payloads (by @WillyJL)
|
||||
- NFC Playlist: Refactor playlist worker, new settings layout, loop setting, controls to move between items (by @acegoal07)
|
||||
- Passy: Misc memory management bugfixes (by @qistoph)
|
||||
- Passy: Misc memory management bugfixes, misc UI improvements (by @qistoph)
|
||||
- Seader: Fix ATS handling (by @NVX), reset SAM on error (by @bettse)
|
||||
- Sentry Safe: New interface, settings & help page (by @H4ckd4ddy)
|
||||
- Seos Compatible: Add keys v2 support with per-device encryption (by @bettse)
|
||||
@@ -58,6 +69,7 @@
|
||||
- NFC:
|
||||
- Fix incorrect Saflok year formula (#433 by @Eltrick)
|
||||
- Fix read crash with unexpectedly large MFC AUTH(0) response, eg with Chameleon Ultra NTAG emualtion (by @WillyJL)
|
||||
- Fix slashes in prefilled filename (by @WillyJL)
|
||||
- FBT: Fix redundant decl for apps using an icon disabled in API (by @WillyJL)
|
||||
|
||||
### Removed:
|
||||
|
||||
+1
-1
Submodule applications/external updated: 321d19b4b3...1027204813
@@ -147,13 +147,14 @@ int32_t archive_app(void* p) {
|
||||
if(path && !furi_string_empty(path)) {
|
||||
archive_set_tab(archive->browser, ArchiveTabBrowser);
|
||||
furi_string_set(archive->browser->path, path);
|
||||
archive->browser->is_root = false;
|
||||
archive->browser->is_root = true;
|
||||
archive_file_browser_set_path(
|
||||
archive->browser,
|
||||
archive->browser->path,
|
||||
archive_get_tab_ext(ArchiveTabBrowser),
|
||||
false,
|
||||
!momentum_settings.show_hidden_files);
|
||||
!momentum_settings.show_hidden_files,
|
||||
furi_string_get_cstr(path));
|
||||
}
|
||||
|
||||
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser);
|
||||
|
||||
@@ -121,7 +121,8 @@ void archive_file_browser_set_path(
|
||||
FuriString* path,
|
||||
const char* filter_ext,
|
||||
bool skip_assets,
|
||||
bool hide_dot_files) {
|
||||
bool hide_dot_files,
|
||||
const char* override_home_path) {
|
||||
furi_assert(browser);
|
||||
if(!browser->worker_running) {
|
||||
browser->worker =
|
||||
@@ -137,6 +138,7 @@ void archive_file_browser_set_path(
|
||||
file_browser_worker_set_config(
|
||||
browser->worker, path, filter_ext, skip_assets, hide_dot_files);
|
||||
}
|
||||
browser->override_home_path = override_home_path;
|
||||
}
|
||||
|
||||
bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx) {
|
||||
@@ -385,7 +387,9 @@ bool archive_is_home(ArchiveBrowserView* browser) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* default_path = archive_get_default_path(archive_get_tab(browser));
|
||||
const char* default_path = browser->override_home_path ?
|
||||
browser->override_home_path :
|
||||
archive_get_default_path(archive_get_tab(browser));
|
||||
return furi_string_cmp_str(browser->path, default_path) == 0;
|
||||
}
|
||||
|
||||
@@ -589,7 +593,12 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
||||
tab == ArchiveTabInternal ? false :
|
||||
!momentum_settings.show_hidden_files;
|
||||
archive_file_browser_set_path(
|
||||
browser, browser->path, archive_get_tab_ext(tab), skip_assets, hide_dot_files);
|
||||
browser,
|
||||
browser->path,
|
||||
archive_get_tab_ext(tab),
|
||||
skip_assets,
|
||||
hide_dot_files,
|
||||
NULL);
|
||||
tab_empty = false; // Empty check will be performed later
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,8 @@ void archive_file_browser_set_path(
|
||||
FuriString* path,
|
||||
const char* filter_ext,
|
||||
bool skip_assets,
|
||||
bool hide_dot_files);
|
||||
bool hide_dot_files,
|
||||
const char* override_home_path);
|
||||
bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx);
|
||||
bool archive_is_file_list_load_required(ArchiveBrowserViewModel* model);
|
||||
void archive_update_offset(ArchiveBrowserView* browser);
|
||||
|
||||
@@ -95,6 +95,7 @@ struct ArchiveBrowserView {
|
||||
bool is_root;
|
||||
FuriTimer* scroll_timer;
|
||||
File* disk_image;
|
||||
const char* override_home_path;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -158,7 +158,8 @@ static bool momentum_app_back_event_callback(void* context) {
|
||||
return scene_manager_handle_back_event(app->scene_manager);
|
||||
}
|
||||
|
||||
static void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* label, FuriString* exe) {
|
||||
static void
|
||||
momentum_app_push_mainmenu_app_raw(MomentumApp* app, FuriString* label, FuriString* exe) {
|
||||
CharList_push_back(app->mainmenu_app_exes, strdup(furi_string_get_cstr(exe)));
|
||||
// Display logic mimics applications/services/gui/modules/menu.c
|
||||
if(furi_string_equal(label, "Momentum")) {
|
||||
@@ -176,6 +177,38 @@ static void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* label,
|
||||
CharList_push_back(app->mainmenu_app_labels, strdup(furi_string_get_cstr(label)));
|
||||
}
|
||||
|
||||
void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* exe) {
|
||||
FuriString* label = furi_string_alloc();
|
||||
if(furi_string_start_with(exe, "/")) {
|
||||
uint8_t unused_icon[FAP_MANIFEST_MAX_ICON_SIZE];
|
||||
uint8_t* unused_icon_ptr = unused_icon;
|
||||
if(!flipper_application_load_name_and_icon(exe, app->storage, &unused_icon_ptr, label)) {
|
||||
const char* end = strrchr(furi_string_get_cstr(exe), '/');
|
||||
furi_string_set(label, end ? end + 1 : furi_string_get_cstr(exe));
|
||||
}
|
||||
momentum_app_push_mainmenu_app_raw(app, label, exe);
|
||||
} else {
|
||||
bool found = false;
|
||||
for(size_t i = 0; !found && i < FLIPPER_APPS_COUNT; i++) {
|
||||
if(!strcmp(furi_string_get_cstr(exe), FLIPPER_APPS[i].name)) {
|
||||
furi_string_set(label, FLIPPER_APPS[i].name);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; !found && i < FLIPPER_EXTERNAL_APPS_COUNT; i++) {
|
||||
if(!strcmp(furi_string_get_cstr(exe), FLIPPER_EXTERNAL_APPS[i].name)) {
|
||||
furi_string_set(label, FLIPPER_EXTERNAL_APPS[i].name);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
// Ignore unknown apps just like in main menu, prevents "ghost" apps when saving
|
||||
if(!furi_string_empty(label)) {
|
||||
momentum_app_push_mainmenu_app_raw(app, label, exe);
|
||||
}
|
||||
}
|
||||
furi_string_free(label);
|
||||
}
|
||||
|
||||
void momentum_app_load_mainmenu_apps(MomentumApp* app) {
|
||||
// Loading logic mimics applications/services/loader/loader_menu.c
|
||||
Stream* stream = file_stream_alloc(app->storage);
|
||||
@@ -198,45 +231,19 @@ void momentum_app_load_mainmenu_apps(MomentumApp* app) {
|
||||
furi_string_set(line, "Momentum");
|
||||
}
|
||||
}
|
||||
if(furi_string_start_with(line, "/")) {
|
||||
if(!flipper_application_load_name_and_icon(
|
||||
line, app->storage, &unused_icon, label)) {
|
||||
const char* end = strrchr(furi_string_get_cstr(line), '/');
|
||||
furi_string_set(label, end ? end + 1 : furi_string_get_cstr(line));
|
||||
}
|
||||
momentum_app_push_mainmenu_app(app, label, line);
|
||||
continue;
|
||||
}
|
||||
bool found = false;
|
||||
for(size_t i = 0; !found && i < FLIPPER_APPS_COUNT; i++) {
|
||||
if(!strcmp(furi_string_get_cstr(line), FLIPPER_APPS[i].name)) {
|
||||
furi_string_set(label, FLIPPER_APPS[i].name);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; !found && i < FLIPPER_EXTERNAL_APPS_COUNT; i++) {
|
||||
if(!strcmp(furi_string_get_cstr(line), FLIPPER_EXTERNAL_APPS[i].name)) {
|
||||
furi_string_set(label, FLIPPER_EXTERNAL_APPS[i].name);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if(furi_string_empty(label)) {
|
||||
// Ignore unknown apps just like in main menu, prevents "ghost" apps when saving
|
||||
continue;
|
||||
}
|
||||
momentum_app_push_mainmenu_app(app, label, line);
|
||||
momentum_app_push_mainmenu_app(app, line);
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
||||
furi_string_set(label, FLIPPER_APPS[i].name);
|
||||
furi_string_set(line, FLIPPER_APPS[i].name);
|
||||
momentum_app_push_mainmenu_app(app, label, line);
|
||||
momentum_app_push_mainmenu_app_raw(app, label, line);
|
||||
}
|
||||
// Until count - 1 because last app is hardcoded below
|
||||
for(size_t i = 0; i < FLIPPER_EXTERNAL_APPS_COUNT - 1; i++) {
|
||||
furi_string_set(label, FLIPPER_EXTERNAL_APPS[i].name);
|
||||
furi_string_set(line, FLIPPER_EXTERNAL_APPS[i].name);
|
||||
momentum_app_push_mainmenu_app(app, label, line);
|
||||
momentum_app_push_mainmenu_app_raw(app, label, line);
|
||||
}
|
||||
}
|
||||
free(unused_icon);
|
||||
|
||||
@@ -111,5 +111,6 @@ typedef enum {
|
||||
|
||||
bool momentum_app_apply(MomentumApp* app);
|
||||
|
||||
void momentum_app_push_mainmenu_app(MomentumApp* app, FuriString* exe);
|
||||
void momentum_app_load_mainmenu_apps(MomentumApp* app);
|
||||
void momentum_app_empty_mainmenu_apps(MomentumApp* app);
|
||||
|
||||
@@ -43,26 +43,7 @@ static void
|
||||
FuriString* temp_path = furi_string_alloc_set_str(browser_options.base_path);
|
||||
|
||||
if(dialog_file_browser_show(app->dialogs, temp_path, temp_path, &browser_options)) {
|
||||
CharList_push_back(app->mainmenu_app_exes, strdup(furi_string_get_cstr(temp_path)));
|
||||
if(is_file_dir) {
|
||||
const char* path = furi_string_get_cstr(temp_path);
|
||||
const char* end = strrchr(path, '/');
|
||||
furi_string_set_str(temp_path, end ? end + 1 : path);
|
||||
} else {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
uint8_t* unused_icon = malloc(FAP_MANIFEST_MAX_ICON_SIZE);
|
||||
flipper_application_load_name_and_icon(
|
||||
temp_path, storage, &unused_icon, temp_path);
|
||||
free(unused_icon);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
if(furi_string_start_with_str(temp_path, "[")) {
|
||||
size_t trim = furi_string_search_str(temp_path, "] ", 1);
|
||||
if(trim != FURI_STRING_FAILURE) {
|
||||
furi_string_right(temp_path, trim + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
CharList_push_back(app->mainmenu_app_labels, strdup(furi_string_get_cstr(temp_path)));
|
||||
momentum_app_push_mainmenu_app(app, temp_path);
|
||||
app->mainmenu_app_index = CharList_size(app->mainmenu_app_labels) - 1;
|
||||
app->save_mainmenu_apps = true;
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
|
||||
+3
-2
@@ -5,8 +5,9 @@ static void
|
||||
MomentumApp* app = context;
|
||||
const char* name = (const char*)index;
|
||||
|
||||
CharList_push_back(app->mainmenu_app_exes, strdup(name));
|
||||
CharList_push_back(app->mainmenu_app_labels, strdup(name));
|
||||
FuriString* exe = furi_string_alloc_set(name);
|
||||
momentum_app_push_mainmenu_app(app, exe);
|
||||
furi_string_free(exe);
|
||||
app->mainmenu_app_index = CharList_size(app->mainmenu_app_labels) - 1;
|
||||
app->save_mainmenu_apps = true;
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
|
||||
@@ -680,6 +680,7 @@ static void nfc_protocol_support_scene_save_name_on_enter(NfcApp* instance) {
|
||||
furi_string_replace(prefix, " Plus", "+"); // NTAG I2C+
|
||||
furi_string_replace(prefix, " (Unknown)", "");
|
||||
furi_string_replace_all(prefix, " ", "_");
|
||||
furi_string_replace_all(prefix, "/", "_");
|
||||
name_generator_make_auto(
|
||||
instance->text_store, NFC_TEXT_STORE_SIZE, furi_string_get_cstr(prefix));
|
||||
furi_string_free(prefix);
|
||||
|
||||
Reference in New Issue
Block a user