aboutsummaryrefslogtreecommitdiff
path: root/src/app.rs
blob: 2fb3b235e5f3dabd1f9665d37c4529f9f7a17642 (plain) (blame)
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
use color_eyre::eyre::Ok;
use ratatui::{
    Frame,
    crossterm::event::{self, Event, KeyCode},
    layout::{Constraint, Layout},
    style::Stylize,
    text::Text,
    widgets::Block,
};

use crate::{
    actions::Signal,
    gentoo::portage::Portage,
    screens::{
        dashboard::DashboardScreen, installed_packages::InstalledPackagesScreen, screen::Screen,
    },
    theme::Theme,
    widgets::tabs::render_tab,
};

#[derive(Debug)]
pub enum ViewState {
    Dashboard = 0,
    InstalledPackages = 1,
    AvailablePackages = 2,
}

#[derive(Debug)]
pub struct App {
    portage: Portage,

    installed_package_screen: InstalledPackagesScreen,
    dashboard_screen: DashboardScreen,

    pub view: ViewState,
}

impl App {
    pub fn new(portage: Portage) -> Self {
        App {
            portage,

            dashboard_screen: DashboardScreen::default(),
            installed_package_screen: InstalledPackagesScreen::default(),

            view: ViewState::InstalledPackages,
        }
    }

    pub fn draw(&mut self, frame: &mut Frame) {
        frame.render_widget(Block::default().bg(Theme::BG), frame.area());

        let layout = Layout::vertical(vec![Constraint::Length(3), Constraint::Fill(1)]);
        let [tab_bar, rest] = frame.area().layout(&layout);

        render_tab(frame, tab_bar, &self.view);

        match self.view {
            ViewState::InstalledPackages => {
                self.installed_package_screen
                    .draw(frame, rest, &self.portage)
            }
            ViewState::Dashboard => {
                self.dashboard_screen.draw(frame, rest, &self.portage);
            }
            _ => frame.render_widget(Text::from("NOT IMPLEMENTED"), rest),
        }
    }

    pub fn update(&mut self) -> color_eyre::Result<bool> {
        if let Event::Key(key) = event::read()? {
            let signal = match self.view {
                crate::app::ViewState::InstalledPackages => {
                    self.installed_package_screen.update(key, &self.portage)
                }

                // Fallback, primarly while implementing
                _ => match key.code {
                    KeyCode::Char('q') => Some(Signal::Quit),
                    KeyCode::Tab => Some(Signal::CycleTab),
                    _ => None,
                },
            };

            if let Some(signal) = signal {
                match signal {
                    Signal::Quit => return Ok(true),
                    Signal::CycleTab => self.cycle_current_tab(),
                }
            }
        }

        Ok(false)
    }

    pub fn cycle_current_tab(&mut self) {
        match self.view {
            ViewState::Dashboard => self.view = ViewState::InstalledPackages,
            ViewState::InstalledPackages => self.view = ViewState::AvailablePackages,
            ViewState::AvailablePackages => self.view = ViewState::Dashboard,
        }
    }
}