- Mp3Player:
* Disable LV_LABEL_LONG_SCROLL_CIRCULAR during playback (flag ENABLE_TITLE_SCROLL_ANIM_WHEN_IDLE) to avoid screen invalidation starving audio_stream
* Single-line controls [-10s][Play/Pause][Stop][+10s] icon-only, volume slider at bottom, no card/toolbar, time label MM:SS / MM:SS updating every sec
* Seek ±10s with proportional byte calc and correct sample count (was byte vs sample bug)
* Safe history persistence: heap buffer (not stack), recursive mkdir, play_history.txt and volume.txt in user data
* History only for >=10min audios, updated on pause/stop/hide, auto-resume latest
* Full-screen history screen with Back button, open via top-right list icon, playing file highlighted CHECKED, tap to resume long or restart short
- VoiceRecorder:
* Fix crash from lv_label_set_long_mode on icon child in list buttons (force DOT only on last child label)
* Force DOT on status and memo list to avoid scroll anim during audio
* Throttle UI updates (1Hz rec, %/sec change play)
Tested on 192.168.68.107, no crash, heap free ~15KB, screenshot verified
- DM: add dl_missing_* fields to AppCtx for sequential queue
- DM player: count_missing_in_season, find_next_missing, download_episode, download_missing_season_start/next
- DM main onResult: auto-continue queue when dl_missing_active, updates status DL X/Y, finishes with done ok/fail
- SdDownloader: file exists returns true (Already on SD) with total=file size, not false
- SdDownloader: set_result_and_close minimal bundle (only success bool) to avoid internal heap OOM crash on close
- SdDownloader: Cancel button becomes Close after done, calls tt_app_stop() directly (manual close per request, auto-close unreliable)
- Fixes crash on close observed in demo mode (file exists) and after download done
Tested on 192.168.68.133: SdDownloader shows Already on SD + Close, DM shows S10 5/6 after sequential, no crash on open/close cycles
- DiscoveryMountain: new UI optimized for episode list (not player anymore)
- Shows episodes for current season, indicates if on SD card (green=On SD, gray=Not DL)
- Per-episode action: download single via SdDownloader or play via Mp3Player
- DL Missing button for missing eps in season (currently single first missing, batch reverted)
- Season selector screen with cached/total counts
- Top-right X close button
- Seasons/episodes cached to cache.json to avoid network fetch every launch
- Fixes: overlay deletion race (deferred timer), ui_timer leak causing crash on close, season selection overwritten by fetch task
- Fixes: unicode ellipsis squares
- SdDownloader: revert to stable single-file mode (batch array caused crashes)
- Remove batch fields and array allocation, keep single url/path download
- Result bundle simple success/path/bytes
- Mp3Player: add resume position support (pos_sec from bundle, total_sec estimate, total_decoded_samples), return position on exit via bundle for DM to save
Tested on 192.168.68.133: opens, shows S10 2/6, Play/DL buttons, close works, no crash on open/close cycles, cache shows 'Loaded from cache, refreshing...'
- Proxy already fixed on FamReynaServer 192.168.68.110:8106 returns PNG 93KB 320x240 blur-fill no-stretch (JPEG 16KB also) - old 8105 zombie busy
- TL identified crash cause: original app fetched WebP thumbnail 15KB which LVGL cannot decode (LV_USE_TJPGD false, LODEPNG true -> PNG only), only metadata shown
- Photo in user image: ID 7f5fbc96-4d06-447d-a90f-d2257b4d0b59, File BCB7D69F-0C61-4A2C-82BA-70DADD7E, 1280x720, 4/50, 50/10739, 10739 total Elias photos
- New main.c 219+: RESIZE_PROXY_URL 8106, /data/immich_cur.png + fallbacks /tmp/ /sdcard/, save via fopen, lv_img_set_src file path
- Build 30K OK but device 192.168.68.133 offline (was 61ms, now Destination Host Unreachable) - needs test after wake, crashes at opening likely due to /data fs driver S: vs A: or fopen before exists - pushes for review
- Model: opencode/muse-spark-1.1 via api.meta.ai same key, tmux visible engineer window 2:engineer on iMac .124, persistent session opencode handles cache better per user
- Branch feature/immich-elias-client
- Define IMMICH_BASE_URL as http://192.168.68.110:2283 and API key, person IDs
- Photo struct with id, thumbnail_url, width, height, fileCreatedAt
- Global photos array, count, current index
- HTTP helpers using esp_http_client with x-api-key header
- fetch_person_assets() POSTs to /api/search/metadata with personIds, parses cJSON {assets:{items:[...]}}
- download_thumbnail() GETs /api/assets/{id}/thumbnail?size=thumbnail (12KB WebP) with fallback note for preview=238KB JPEG for RAM safety
- UI: toolbar, title "Elias - 10739 photos", count label, img placeholder, prev/next 60x40 bottom, info label with asset id/date/size
- FreeRTOS tasks for fetch + thumb to avoid blocking LVGL
- Proper aspect no stretch, uses lvgl_get_text_font(SMALL/DEFAULT/LARGE)
- Builds clean for esp32s3, 0 missing symbols verified via nm -D
- CMake: fix TACTILITY_SDK_PATH and cJSON inclusion via json component source
- Tested Immich API locally: metadata search returns 10739-capable, thumbnail endpoints working
Co-Authored-By: internal-model
- Merged CI workflow to include all local apps + EspNowBridge
- HelloWorld manifest now V2 format from upstream (sdk 0.8.0-dev)
- Kept local SfxEngine enhancements (polyphonic gate, auto-normalization)
- Brings main up to date with origin/main 25b966a
Root cause: LVGL9 canvas = lv_image backed by draw_buf with image cache.
Mutating raw uint16_t* buffer without lv_image_cache_drop + lv_draw_buf_invalidate_cache
leaves stale texture (gray/black). Only label (FPS) updated via lv_label_set_text_fmt,
so symptom = FPS counter works, game invisible.
Fix:
- fb_native typed uint16_t* raw RGB565, not lv_color16_t bitfield (endian bug)
- keep lv_draw_buf_t* from lv_canvas_get_draw_buf()
- each frame after gb_run_frame(): invalidate_cache + cache_drop + invalidate
- initial buffer fill check pattern removed, added lines_drawn debug in FPS label
- forward-decl lv_image_cache_drop (not in public SDK headers but firmware exports it)
- requires firmware feature/gameboy-canvas-full-api:
lv_draw_buf_invalidate_cache, lv_image_cache_drop, lv_canvas_get_draw_buf,
lv_image_set_scale/pivot, display resolution
SDK 0.8.0-dev built with IDF 5.5.2 - 0 undefined beyond firmware exports.
Builds to 50K GameBoy.app
Also preserves mDNS browse API from parent branch (Mdns.h/cpp, tt_mdns.h/cpp)
which sits on top of 60764979 'kidsOS-XXXX' mdns init.
- use lv_display_get_*_resolution to compute available area
- apply lv_image_set_scale 2x/3x + pivot center when display large enough
- removes previous comment hack 'avoid non-exported LVGL transform symbols'
- now requires firmware feature/gameboy-canvas-full-api (symbols exported)
SDK: 0.8.0-dev built with IDF 5.5.2, 0 missing symbols
- VoiceRecorder now explicitly unmutes input and sets 100% gain (24dB) after audio_stream_open_input
- Matches firmware fix c7dc66e0 BOTH complementary open + close ref-count
- Mp3Player/BookPlayer already using audio-stream for output (fixes fast playback)
- Mp3Player: sdk 0.7->0.8.0-dev, find audio-stream device, open_output with resampler (hz/ch), write via audio_stream_write, close on pause
- BookPlayer: close/open per format change via AudioStreamConfig, write via stream
- VoiceRecorder: input_handle open_input 16k/mono via audio_stream_read, output_handle open_output file rate via write/resampler
- ES8311 native 44100, old direct I2S at 16k caused 4.096MHz MCLK vs 11.29MHz -> fast playback
- Brick game correct because it uses audio-stream resampler path
- Mp3Player: increase task stack 4096->6144, prio 5->6, remove taskYIELD causing audio gaps
- VoiceRecorder: configure I2S as stereo for ES7210 (dual mic) like working MicroPython,
then downmix left channel to mono WAV to fix low-pitch mic-like recording
- Single verse fullscreen, auto-advances every minute, tap toggles chrome
- Offline WEB bible split per-book: books.json + 66 bin/idx pairs (~4.1MB)
- bin = NUL-terminated UTF-8 concatenation, idx = {offset,cnum,vnum}
- RAM tiny: loads one book at a time, biggest Psalms ~215KB vs 3.8MB monolith
- Adaptive text scaling by length: <40 ultra-large (Jesus wept), <100 large,
100-200 default, 200-350 small, 350+ compact (Esther 8:9 492c)
- Persistence via user_data_path: progress.txt + favorites.txt (like BookPlayer)
- LVGL fixes: use lvgl_get_text_font(FONT_SIZE_*) - direct montserrat not exported,
no gradients (bg_grad_color not exported), LV_OPA_95 -> OPA_COVER, format-truncation werror silenced
- Deploys to 192.168.68.112 via PUT /api/apps/install (dashboard port 80, dev 6666 closed)
Tested: build esp32s3 local-sdk 0 missing symbols, 4.2MB .app, screenshot Gen 2:10
Refs: tools/convert_bible.py regenerates assets from WEB source