#pragma once #include #include #include #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #ifdef __cplusplus extern "C" { #endif #define TAG "DM" #define PB "http://192.168.68.110:8095" #define DM_DIR "/sdcard/dm" #define STATE_PATH "/sdcard/apps/one.tactility.discoverymountain/userdata/state.json" #define MAX_SEASONS 40 #define MAX_EPS 400 #define MP3_BUF 16384 typedef struct { int num; } SeasonInfo; typedef struct { char title[128]; char slug[96]; int season; int ep_num; char audio_url[256]; bool seen; } EpInfo; typedef struct { char slug[96]; int pos; } SavedPos; typedef struct { SeasonInfo seasons[MAX_SEASONS]; int season_cnt; EpInfo eps[MAX_EPS]; int ep_cnt; int cur_season; int cur_ep_idx; struct Device* stream_dev; AudioStreamHandle stream_handle; bool is_playing; bool is_paused; bool need_stop; TaskHandle_t play_handle; TaskHandle_t fetch_handle; TaskHandle_t dl_handle; int pos_sec; int total_sec; int volume; int last_pct; lv_obj_t *lbl_title, *lbl_meta, *bar, *lbl_time, *lbl_status, *btn_play; lv_obj_t *overlay, *dropdown; // Download UI lv_obj_t *dl_overlay; lv_obj_t *dl_bar; lv_obj_t *dl_lbl_pct; lv_obj_t *dl_lbl_detail; lv_obj_t *dl_lbl_title; lv_obj_t *dl_lbl_sub; char cur_title[128]; char last_slug[96]; bool fetching; bool downloading; int dl_total; int dl_expected; int dl_last_ui_update; bool dl_cancel_req; char dl_ep_title[128]; char dl_slug[96]; int dl_season; int dl_ep_num; int dl_last_pct; // Per-episode resume SavedPos saved_pos[MAX_EPS]; int saved_pos_cnt; int last_save_tick; } AppCtx; extern AppCtx G; #ifdef __cplusplus } #endif