Skip to content

Commit 8f16dbb

Browse files
committed
Merge branch 'dev' into release
2 parents 49e458f + 8608ba0 commit 8f16dbb

File tree

10 files changed

+183
-80
lines changed

10 files changed

+183
-80
lines changed

CHANGELOG.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
### New changes
2-
* iButton: **Temp Fix of non working emulation on Metakom and Cyfral protocols**
3-
* Archive and FileBrowser: **Sort files and folders alphabetically.** Added a "Internal" tab to the Browser (only in DEBUG mode), other misc changes (by @ClaraCrazy and @Willy-JL | PR #327)
4-
* SubGHz: Custom modulation for lrs pagers and added frequency 467.75 to default list (by @jbohack | PR #328)
5-
* SubGHz: **Small fixes in SubGHz HAL**
2+
* Archive and FileBrowser: Fixed #332 (large folders parse issue)
3+
* Archive and FileBrowser: Fixed navigation issues and improved performance (by @Willy-JL | PR #333)
4+
* SubGHz -> HAL: **Fixed external CC1101 module issues** (transmission now works correctly) (fixed issue #331)
5+
* SubGHz: Use 17 (1W) pin for subghz debug mode
66

77
#### [🎲 Download latest extra apps pack](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps)
88

applications/main/archive/helpers/archive_browser.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,14 @@ static void archive_list_load_cb(void* context, uint32_t list_load_offset) {
5757
false);
5858
}
5959

60-
static void
61-
archive_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) {
60+
static void archive_list_item_cb(
61+
void* context,
62+
FuriString* item_path,
63+
uint32_t idx,
64+
bool is_folder,
65+
bool is_last) {
6266
furi_assert(context);
67+
UNUSED(idx);
6368
ArchiveBrowserView* browser = (ArchiveBrowserView*)context;
6469

6570
if(!is_last) {

applications/main/archive/views/archive_browser_view.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ static bool archive_view_input(InputEvent* event, void* context) {
482482
model->scroll_counter = 0;
483483
}
484484
},
485-
true);
485+
false);
486486
archive_update_offset(browser);
487487
}
488488

applications/main/subghz/scenes/subghz_scene_ext_module_settings.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const char* const radio_modules_variables_text[] = {
1313
#define DEBUG_P_COUNT 2
1414
const char* const debug_pin_text[DEBUG_P_COUNT] = {
1515
"OFF",
16-
"A7",
16+
"17(1W)",
1717
};
1818

1919
static void subghz_scene_ext_module_changed(VariableItem* item) {

applications/main/subghz/subghz_i.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ void subghz_hopper_update(SubGhz* subghz) {
598598

599599
void subghz_speaker_on(SubGhz* subghz) {
600600
if(subghz->txrx->debug_pin_state) {
601-
furi_hal_subghz_set_async_mirror_pin(&gpio_ext_pa7);
601+
furi_hal_subghz_set_async_mirror_pin(&ibutton_gpio);
602602
}
603603

604604
if(subghz->txrx->speaker_state == SubGhzSpeakerStateEnable) {
@@ -643,7 +643,7 @@ void subghz_speaker_mute(SubGhz* subghz) {
643643

644644
void subghz_speaker_unmute(SubGhz* subghz) {
645645
if(subghz->txrx->debug_pin_state) {
646-
furi_hal_subghz_set_async_mirror_pin(&gpio_ext_pa7);
646+
furi_hal_subghz_set_async_mirror_pin(&ibutton_gpio);
647647
}
648648
if(subghz->txrx->speaker_state == SubGhzSpeakerStateEnable) {
649649
if(furi_hal_speaker_is_mine()) {

applications/main/subghz/views/subghz_frequency_analyzer.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121
#define MAX_HISTORY 4
2222

2323
static const uint32_t subghz_frequency_list[] = {
24-
300000000, 302757000, 303875000, 304250000, 307000000, 307500000, 307800000, 309000000,
25-
310000000, 312000000, 312100000, 313000000, 313850000, 314000000, 314350000, 314980000,
26-
315000000, 318000000, 330000000, 345000000, 348000000, 350000000, 387000000, 390000000,
27-
418000000, 433075000, 433220000, 433420000, 433657070, 433889000, 433920000, 434075000,
28-
434176948, 434390000, 434420000, 434775000, 438900000, 440175000, 464000000, 467750000, 779000000,
29-
868350000, 868400000, 868800000, 868950000, 906400000, 915000000, 925000000, 928000000};
24+
300000000, 302757000, 303875000, 304250000, 307000000, 307500000, 307800000,
25+
309000000, 310000000, 312000000, 312100000, 313000000, 313850000, 314000000,
26+
314350000, 314980000, 315000000, 318000000, 330000000, 345000000, 348000000,
27+
350000000, 387000000, 390000000, 418000000, 433075000, 433220000, 433420000,
28+
433657070, 433889000, 433920000, 434075000, 434176948, 434390000, 434420000,
29+
434775000, 438900000, 440175000, 464000000, 467750000, 779000000, 868350000,
30+
868400000, 868800000, 868950000, 906400000, 915000000, 925000000, 928000000};
3031

3132
typedef enum {
3233
SubGhzFrequencyAnalyzerStatusIDLE,

applications/services/gui/modules/file_browser.c

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,23 @@ typedef enum {
3434
} BrowserItemType;
3535

3636
typedef struct {
37+
uint32_t unsorted_idx;
3738
FuriString* path;
3839
BrowserItemType type;
3940
uint8_t* custom_icon_data;
4041
FuriString* display_name;
4142
} BrowserItem_t;
4243

4344
static void BrowserItem_t_init(BrowserItem_t* obj) {
45+
obj->unsorted_idx = 0;
4446
obj->type = BrowserItemTypeLoading;
4547
obj->path = furi_string_alloc();
4648
obj->display_name = furi_string_alloc();
4749
obj->custom_icon_data = NULL;
4850
}
4951

5052
static void BrowserItem_t_init_set(BrowserItem_t* obj, const BrowserItem_t* src) {
53+
obj->unsorted_idx = src->unsorted_idx;
5154
obj->type = src->type;
5255
obj->path = furi_string_alloc_set(src->path);
5356
obj->display_name = furi_string_alloc_set(src->display_name);
@@ -60,6 +63,7 @@ static void BrowserItem_t_init_set(BrowserItem_t* obj, const BrowserItem_t* src)
6063
}
6164

6265
static void BrowserItem_t_set(BrowserItem_t* obj, const BrowserItem_t* src) {
66+
obj->unsorted_idx = src->unsorted_idx;
6367
obj->type = src->type;
6468
furi_string_set(obj->path, src->path);
6569
furi_string_set(obj->display_name, src->display_name);
@@ -157,8 +161,12 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context);
157161
static void
158162
browser_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root);
159163
static void browser_list_load_cb(void* context, uint32_t list_load_offset);
160-
static void
161-
browser_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last);
164+
static void browser_list_item_cb(
165+
void* context,
166+
FuriString* item_path,
167+
uint32_t idx,
168+
bool is_folder,
169+
bool is_last);
162170
static void browser_long_load_cb(void* context);
163171

164172
static void file_browser_scroll_timer_callback(void* context) {
@@ -347,7 +355,7 @@ static void browser_update_offset(FileBrowser* browser) {
347355
CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0);
348356
}
349357
},
350-
false);
358+
true);
351359
}
352360

353361
static void
@@ -379,7 +387,7 @@ static void
379387
model->list_loading = true;
380388
model->folder_loading = false;
381389
},
382-
true);
390+
false);
383391
browser_update_offset(browser);
384392

385393
file_browser_worker_load(browser->worker, load_offset, ITEM_LIST_LEN_MAX);
@@ -412,13 +420,18 @@ static void browser_list_load_cb(void* context, uint32_t list_load_offset) {
412420
BrowserItem_t_clear(&back_item);
413421
}
414422

415-
static void
416-
browser_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) {
423+
static void browser_list_item_cb(
424+
void* context,
425+
FuriString* item_path,
426+
uint32_t idx,
427+
bool is_folder,
428+
bool is_last) {
417429
furi_assert(context);
418430
FileBrowser* browser = (FileBrowser*)context;
419431

420432
BrowserItem_t item;
421433
item.custom_icon_data = NULL;
434+
item.unsorted_idx = idx;
422435

423436
if(!is_last) {
424437
item.path = furi_string_alloc_set(item_path);
@@ -454,7 +467,7 @@ static void
454467
items_array_push_back(model->items, item);
455468
// TODO: calculate if element is visible
456469
},
457-
true);
470+
false);
458471
furi_string_free(item.display_name);
459472
furi_string_free(item.path);
460473
if(item.custom_icon_data) {
@@ -465,10 +478,28 @@ static void
465478
browser->view,
466479
FileBrowserModel * model,
467480
{
468-
items_array_sort(model->items);
481+
if(model->item_cnt < 430) {
482+
FuriString* selected = NULL;
483+
if(model->item_idx > 0) {
484+
selected = furi_string_alloc_set(
485+
items_array_get(model->items, model->item_idx)->path);
486+
}
487+
488+
items_array_sort(model->items);
489+
490+
if(selected != NULL) {
491+
for(uint32_t i = 0; i < model->item_cnt; i++) {
492+
if(!furi_string_cmp(items_array_get(model->items, i)->path, selected)) {
493+
model->item_idx = i;
494+
break;
495+
}
496+
}
497+
}
498+
}
469499
model->list_loading = false;
470500
},
471-
true);
501+
false);
502+
browser_update_offset(browser);
472503
}
473504
}
474505

@@ -652,7 +683,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
652683
model->scroll_counter = 0;
653684
}
654685
},
655-
true);
686+
false);
656687
browser_update_offset(browser);
657688
consumed = true;
658689
}
@@ -667,10 +698,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
667698
if(browser_is_item_in_array(model, model->item_idx)) {
668699
selected_item =
669700
items_array_get(model->items, model->item_idx - model->array_offset);
670-
select_index = model->item_idx;
671-
if((!model->is_root) && (select_index > 0)) {
672-
select_index -= 1;
673-
}
701+
select_index = selected_item->unsorted_idx;
674702
}
675703
},
676704
false);

applications/services/gui/modules/file_browser_worker.c

Lines changed: 96 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,12 @@ static bool browser_folder_init(
189189
return state;
190190
}
191191

192-
static bool
193-
browser_folder_load(BrowserWorker* browser, FuriString* path, uint32_t offset, uint32_t count) {
192+
// Load files list by chunks, like it was originally, not compatible with sorting, sorting needs to be disabled to use this
193+
static bool browser_folder_load_chunked(
194+
BrowserWorker* browser,
195+
FuriString* path,
196+
uint32_t offset,
197+
uint32_t count) {
194198
FileInfo file_info;
195199

196200
Storage* storage = furi_record_open(RECORD_STORAGE);
@@ -202,39 +206,89 @@ static bool
202206

203207
uint32_t items_cnt = 0;
204208

205-
bool ret = false;
206209
do {
207210
if(!storage_dir_open(directory, furi_string_get_cstr(path))) {
208211
break;
209212
}
210213

211-
// items_cnt = 0;
212-
// while(items_cnt < offset) {
213-
// if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) {
214-
// break;
215-
// }
216-
// if(storage_file_get_error(directory) == FSE_OK) {
217-
// furi_string_set(name_str, name_temp);
218-
// if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) {
219-
// items_cnt++;
220-
// }
221-
// } else {
222-
// break;
223-
// }
224-
// }
225-
// if(items_cnt != offset) {
226-
// break;
227-
// }
228-
229-
// FLIPPER DEVS MOMENT
230-
// this used to load the file list in chunks, and then sort it...
231-
// so while scrolling, it loads more files and sorts them...
232-
// chances are, the new files are higher in the sorted list...
233-
// so the files keep shifting around while scrolling...
234-
// now this does something intelligent and loads all in one go.
235-
// might take a few milliseconds longer, but atleast it works :kekw:
236-
UNUSED(offset);
237-
UNUSED(count);
214+
items_cnt = 0;
215+
while(items_cnt < offset) {
216+
if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) {
217+
break;
218+
}
219+
if(storage_file_get_error(directory) == FSE_OK) {
220+
furi_string_set(name_str, name_temp);
221+
if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) {
222+
items_cnt++;
223+
}
224+
} else {
225+
break;
226+
}
227+
}
228+
if(items_cnt != offset) {
229+
break;
230+
}
231+
232+
if(browser->list_load_cb) {
233+
browser->list_load_cb(browser->cb_ctx, offset);
234+
}
235+
236+
items_cnt = 0;
237+
while(items_cnt < count) {
238+
if(!storage_dir_read(directory, &file_info, name_temp, FILE_NAME_LEN_MAX)) {
239+
break;
240+
}
241+
if(storage_file_get_error(directory) == FSE_OK) {
242+
furi_string_set(name_str, name_temp);
243+
if(browser_filter_by_name(browser, name_str, (file_info.flags & FSF_DIRECTORY))) {
244+
furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp);
245+
if(browser->list_item_cb) {
246+
browser->list_item_cb(
247+
browser->cb_ctx,
248+
name_str,
249+
items_cnt,
250+
(file_info.flags & FSF_DIRECTORY),
251+
false);
252+
}
253+
items_cnt++;
254+
}
255+
} else {
256+
break;
257+
}
258+
}
259+
if(browser->list_item_cb) {
260+
browser->list_item_cb(browser->cb_ctx, NULL, 0, false, true);
261+
}
262+
} while(0);
263+
264+
furi_string_free(name_str);
265+
266+
storage_dir_close(directory);
267+
storage_file_free(directory);
268+
269+
furi_record_close(RECORD_STORAGE);
270+
271+
return (items_cnt == count);
272+
}
273+
274+
// Load all files at once, may cause memory overflow so need to limit that to about 400 files
275+
static bool browser_folder_load_full(BrowserWorker* browser, FuriString* path) {
276+
FileInfo file_info;
277+
278+
Storage* storage = furi_record_open(RECORD_STORAGE);
279+
File* directory = storage_file_alloc(storage);
280+
281+
char name_temp[FILE_NAME_LEN_MAX];
282+
FuriString* name_str;
283+
name_str = furi_string_alloc();
284+
285+
uint32_t items_cnt = 0;
286+
287+
bool ret = false;
288+
do {
289+
if(!storage_dir_open(directory, furi_string_get_cstr(path))) {
290+
break;
291+
}
238292
if(browser->list_load_cb) {
239293
browser->list_load_cb(browser->cb_ctx, 0);
240294
}
@@ -245,13 +299,17 @@ static bool
245299
furi_string_printf(name_str, "%s/%s", furi_string_get_cstr(path), name_temp);
246300
if(browser->list_item_cb) {
247301
browser->list_item_cb(
248-
browser->cb_ctx, name_str, (file_info.flags & FSF_DIRECTORY), false);
302+
browser->cb_ctx,
303+
name_str,
304+
items_cnt,
305+
(file_info.flags & FSF_DIRECTORY),
306+
false);
249307
}
250308
items_cnt++;
251309
}
252310
}
253311
if(browser->list_item_cb) {
254-
browser->list_item_cb(browser->cb_ctx, NULL, false, true);
312+
browser->list_item_cb(browser->cb_ctx, NULL, 0, false, true);
255313
}
256314
ret = true;
257315
} while(0);
@@ -360,7 +418,12 @@ static int32_t browser_worker(void* context) {
360418
if(flags & WorkerEvtLoad) {
361419
FURI_LOG_D(
362420
TAG, "Load offset: %lu cnt: %lu", browser->load_offset, browser->load_count);
363-
browser_folder_load(browser, path, browser->load_offset, browser->load_count);
421+
if(items_cnt > 430) {
422+
browser_folder_load_chunked(
423+
browser, path, browser->load_offset, browser->load_count);
424+
} else {
425+
browser_folder_load_full(browser, path);
426+
}
364427
}
365428

366429
if(flags & WorkerEvtStop) {

0 commit comments

Comments
 (0)