text/plain
•
4.30 KB
•
146 lines
#include "podcast_sync_screen.h"
#include <stdio.h>
#include <stdlib.h>
#include "../podcast_sync.h"
#include "../topbar.h"
static void cancel_event_cb(lv_event_t* e) {
(void)e;
podcast_sync_cancel();
navigate_back(SCREEN_PODCASTS);
}
static void back_event_cb(lv_event_t* e) {
if (lv_event_get_code(e) == LV_EVENT_CLICKED) {
cancel_event_cb(e);
}
}
ui_state_t setup_podcast_sync_screen(lv_obj_t* parent) {
podcast_sync_screen_state_t* state =
calloc(1, sizeof(podcast_sync_screen_state_t));
topbar_set_title("Syncing");
// Create container for vertical layout
lv_obj_t* cont = lv_obj_create(parent);
lv_obj_set_size(cont, SCREEN_WIDTH, SCREEN_HEIGHT - TOPBAR_H);
lv_obj_align(cont, LV_ALIGN_TOP_LEFT, 0, TOPBAR_H);
lv_obj_set_style_bg_opa(cont, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(cont, 0, 0);
lv_obj_set_style_pad_all(cont, 8, 0);
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER,
LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_row(cont, 8, 0);
// Status label
state->label = lv_label_create(cont);
lv_label_set_text(state->label, "Starting sync...");
lv_obj_set_width(state->label, SCREEN_WIDTH - 16);
lv_label_set_long_mode(state->label, LV_LABEL_LONG_SCROLL_CIRCULAR);
// Progress bar
state->bar = lv_bar_create(cont);
lv_obj_set_size(state->bar, SCREEN_WIDTH - 16, 10);
lv_bar_set_range(state->bar, 0, 100);
lv_bar_set_value(state->bar, 0, LV_ANIM_OFF);
// Back/Cancel button
state->back_btn = lv_btn_create(cont);
lv_obj_set_size(state->back_btn, SCREEN_WIDTH - 16, 28);
lv_obj_t* btn_label = lv_label_create(state->back_btn);
lv_label_set_text(btn_label, "Cancel");
lv_obj_center(btn_label);
lv_obj_add_event_cb(state->back_btn, back_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(state->back_btn, cancel_event_cb, LV_EVENT_CANCEL,
NULL);
lv_group_add_obj(lv_group_get_default(), state->back_btn);
lv_group_focus_obj(state->back_btn);
// Start sync — single feed if podcast_url is set, otherwise all
if (app_state.podcast_url[0]) {
podcast_sync_start_single(app_state.podcast_title,
app_state.podcast_url);
app_state.podcast_url[0] = '\0';
} else {
podcast_sync_start();
}
state->sync_active = true;
return (ui_state_t){.type = SCREEN_PODCAST_SYNC, .podcast_sync = state};
}
void free_podcast_sync_screen(podcast_sync_screen_state_t* state) {
if (!state) {
return;
}
free(state);
}
void update_podcast_sync_screen(podcast_sync_screen_state_t* state) {
if (!state || !state->sync_active) {
return;
}
bool more = podcast_sync_step();
const podcast_sync_status_t* st = podcast_sync_get_status();
// Update progress
int progress = 0;
if (st->total_feeds > 0) {
// Weight: feed downloads are ~10%, episode downloads are ~90%
int feed_progress = st->current_feed * 100 / st->total_feeds;
if (st->total_episodes > 0) {
int ep_progress = st->current_episode * 100 / st->total_episodes;
progress = (feed_progress * 10 + ep_progress * 90) / 100;
} else {
progress = feed_progress;
}
}
lv_bar_set_value(state->bar, progress, LV_ANIM_OFF);
// Update label
if (st->current_action) {
char buf[128];
if (st->total_episodes > 0) {
snprintf(buf, sizeof(buf), "[%d/%d] %s", st->current_episode,
st->total_episodes, st->current_action);
} else if (st->total_feeds > 0) {
snprintf(buf, sizeof(buf), "Feed %d/%d: %s", st->current_feed + 1,
st->total_feeds, st->current_action);
} else {
snprintf(buf, sizeof(buf), "%s", st->current_action);
}
lv_label_set_text(state->label, buf);
}
if (!more) {
state->sync_active = false;
lv_bar_set_value(state->bar, 100, LV_ANIM_OFF);
char buf[256];
if (st->errors > 0 && st->last_error[0]) {
if (st->errors == 1) {
snprintf(buf, sizeof(buf), "Error: %s", st->last_error);
} else {
snprintf(buf, sizeof(buf), "%d errors, last: %s", st->errors,
st->last_error);
}
} else {
snprintf(buf, sizeof(buf), "Done. %d error%s", st->errors,
st->errors == 1 ? "" : "s");
}
lv_label_set_text(state->label, buf);
topbar_set_title("Sync Done");
// Change button text to "Back"
lv_obj_t* btn_label = lv_obj_get_child(state->back_btn, 0);
if (btn_label) {
lv_label_set_text(btn_label, "Back");
}
}
}