Skip to main content

fast_down_gui/core/
app.rs

1use crate::{
2    core::{DownloadEvent, TaskSet, apply_progress_diff},
3    fmt::format_size,
4    persist::{self, Database},
5    ui::{self, EntryData, MainWindow},
6    utils::LogErr,
7};
8use slint::{Model, Weak};
9
10#[derive(Clone)]
11pub struct App {
12    pub db: Database,
13    pub task_set: TaskSet<i32>,
14    pub ui: Weak<MainWindow>,
15}
16
17impl App {
18    pub fn update_ui_row<F>(&self, gid: i32, mutator: F)
19    where
20        F: FnOnce(usize, &mut EntryData) + Send + 'static,
21    {
22        let _ = self.ui.upgrade_in_event_loop(move |ui| {
23            let list_model = ui.get_all_list();
24            for (row, mut data) in list_model.iter().enumerate() {
25                if data.gid == gid {
26                    mutator(row, &mut data);
27                    list_model.set_row_data(row, data);
28                    break;
29                }
30            }
31        });
32    }
33
34    /// 创建下载过程中的事件处理器
35    pub fn create_download_handler(
36        &self,
37        gid: i32,
38    ) -> impl FnMut(DownloadEvent) + Send + Sync + 'static {
39        let app = self.clone();
40        let mut file_size = 0;
41        move |event| match event {
42            DownloadEvent::Info(info) => {
43                file_size = info.file_size;
44                let _ = app
45                    .db
46                    .init_entry(gid, *info.clone())
47                    .log_err("数据库插入条目失败");
48                app.update_ui_row(gid, move |_, data| {
49                    data.status = ui::Status::Running;
50                    data.filename = info.file_name.into();
51                    data.path = info.file_path.to_string_lossy().as_ref().into();
52                    data.total = format_size(info.file_size as f64).into();
53                });
54            }
55            DownloadEvent::Progress(p) => {
56                app.db.update_entry(gid, p.progress.clone(), p.elapsed);
57                app.update_ui_row(gid, move |_, data| {
58                    data.downloaded = p.downloaded;
59                    data.speed = p.speed;
60                    data.avg_speed = p.avg_speed;
61                    data.percentage = p.percentage;
62                    data.remaining_time = p.remaining_time;
63                    data.remaining_size = p.remaining_size;
64                    data.time = p.time;
65                    if file_size > 0 {
66                        data.progress = apply_progress_diff(&data.progress, &p.progress, file_size);
67                    }
68                });
69            }
70            DownloadEvent::End { is_cancelled } => {
71                let db_status = if is_cancelled {
72                    persist::Status::Paused
73                } else {
74                    persist::Status::Completed
75                };
76                let ui_status = if is_cancelled {
77                    ui::Status::Paused
78                } else {
79                    ui::Status::Completed
80                };
81                app.db.update_status(gid, db_status);
82                app.update_ui_row(gid, move |_, data| data.status = ui_status);
83            }
84        }
85    }
86}