1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::{error::Error, sync::Arc};

use crossterm::event::KeyEvent;
use magnetease::{MagneteaseError, MagneteaseResult};
use transmission_rpc::types::{FreeSpace, SessionStats, Torrent};

use crate::status_task::StatusTask;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Action {
    // General
    HardQuit,
    Quit,
    Close,
    Render,
    Up,
    Down,
    Left,
    Right,
    ScrollUpBy(u8),
    ScrollDownBy(u8),
    ScrollUpPage,
    ScrollDownPage,
    Home,
    End,
    Confirm,
    Select,
    ShowHelp,
    Search,
    ChangeFocus,
    ChangeTab(u8),
    XdgOpen,
    Input(KeyEvent),
    MoveToColumnLeft,
    MoveToColumnRight,
    // Torrents Tab
    ShowStats,
    ShowFiles,
    Pause,
    Delete,
    AddMagnet,
    MoveTorrent,
    ChangeCategory,
    // Search Tab
    ShowProvidersInfo,
}

pub enum UpdateAction {
    // General
    SwitchToInputMode,
    SwitchToNormalMode,
    Error(Box<ErrorMessage>),
    // Torrents Tab
    SessionStats(Arc<SessionStats>),
    FreeSpace(Arc<FreeSpace>),
    UpdateTorrents(Vec<Torrent>),
    UpdateCurrentTorrent(Box<Torrent>),
    SearchFilterApply(String),
    SearchFilterClear,
    CancelTorrentTask,
    // Search Tab
    SearchStarted,
    ProviderResult(MagneteaseResult),
    ProviderError(MagneteaseError),
    SearchFinished,
    // Task Manager's Status Task
    StatusTaskClear,
    StatusTaskSuccess,
    StatusTaskFailure,
    StatusTaskSet(StatusTask),
    StatusTaskSetSuccess(StatusTask),
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ErrorMessage {
    pub title: String,
    pub description: String,
    pub source: String,
}

impl ErrorMessage {
    pub fn new(
        title: impl Into<String>,
        message: impl Into<String>,
        error: Box<dyn Error>,
    ) -> Self {
        Self {
            title: title.into(),
            description: message.into(),
            source: error.to_string(),
        }
    }
}

impl Action {
    pub fn is_render(&self) -> bool {
        *self == Self::Render
    }

    pub fn is_hard_quit(&self) -> bool {
        *self == Self::HardQuit
    }

    pub fn is_quit(&self) -> bool {
        *self == Self::HardQuit || *self == Self::Quit
    }

    pub fn is_soft_quit(&self) -> bool {
        self.is_quit() || *self == Self::Close
    }
}