Skip to content

Commit

Permalink
re-feat: rename ethylene-amd to amdhelper
Browse files Browse the repository at this point in the history
  • Loading branch information
alvindimas05 committed Oct 7, 2024
1 parent d6fd1cc commit a1f7e1a
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
9 changes: 9 additions & 0 deletions amdhelper-tui/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "amdhelper-tui"
version = "0.1.0"
edition = "2021"

[dependencies]
amdhelper = { path = "../amdhelper" }
crossterm = "0.28.1"
ratatui = "0.28.1"
168 changes: 168 additions & 0 deletions amdhelper-tui/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#![warn(clippy::nursery, unused_extern_crates)]

use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
use ethylene_amd::{apply_chromium_patch, get_apps, get_patches, patch::{chromium::ChromiumPatch, EthylenePatch}, EthyleneApp};
use ratatui::{
buffer::Buffer,
layout::{Alignment, Rect},
style::{palette::tailwind::SLATE, Modifier, Style, Stylize},
text::Line,
widgets::{
block::{Position, Title},
Block, List, ListItem, ListState, StatefulWidget, Widget,
},
DefaultTerminal,
};
fn main() -> std::io::Result<()> {
let mut terminal = ratatui::init();
terminal.clear()?;

let app_result = App::default().and_then(|v| v.run(&mut terminal));
ratatui::restore();
app_result
}

const SELECTED_STYLE: Style = Style::new().bg(SLATE.c300).add_modifier(Modifier::BOLD);

struct App {
exit: bool,
app_list: AppList,
}

struct AppList {
items: Vec<EthyleneApp>,
selected_items: Vec<usize>,
state: ListState,
}

impl App {
fn default() -> std::io::Result<Self> {
let patches = get_patches();
Ok(Self {
exit: false,
app_list: AppList {
items: get_apps(&patches)?,
selected_items: vec![],
state: ListState::default(),
},
})
}

pub fn run(mut self, terminal: &mut DefaultTerminal) -> std::io::Result<()> {
while !self.exit {
terminal.draw(|frame| frame.render_widget(&mut self, frame.area()))?;
self.handle_events()?;
}
Ok(())
}

fn handle_events(&mut self) -> std::io::Result<()> {
match crossterm::event::read()? {
Event::Key(key_event) if key_event.kind == KeyEventKind::Press => {
self.handle_key_event(key_event)
}
_ => {}
};
Ok(())
}

fn handle_key_event(&mut self, key_event: KeyEvent) {
match key_event.code {
KeyCode::Char('q') | KeyCode::Esc => self.exit(),
KeyCode::Char('j') | KeyCode::Down => self.select_next(),
KeyCode::Char('k') | KeyCode::Up => self.select_previous(),
KeyCode::Char('a') => self.apply_patches(),
KeyCode::Enter => self.select_item(),
_ => {}
}
}

fn apply_patches(&mut self) {
if self.app_list.selected_items.len() < 1 { return }
apply_chromium_patch(ChromiumPatch, self.get_selected_apps());

self.app_list.selected_items = vec![];
}

fn get_selected_apps(&mut self) -> Vec<&EthyleneApp> {
self.app_list.selected_items.iter().map(|i| self.app_list.items.get(*i).unwrap()).collect::<Vec<&EthyleneApp>>()
}

fn exit(&mut self) {
self.exit = true;
}

fn select_item(&mut self) {
let selected_index = self.app_list.state.selected().unwrap();
let selected_items = self.app_list.selected_items.clone();
if selected_items.contains(&selected_index) {
self.app_list.selected_items.remove(
selected_items
.iter()
.position(|item| *item == selected_index)
.unwrap(),
);
} else {
self.app_list.selected_items.push(selected_index);
}
}

fn select_next(&mut self) {
self.app_list.state.select_next();
}

fn select_previous(&mut self) {
self.app_list.state.select_previous();
}
}

impl Widget for &mut App {
fn render(self, area: Rect, buf: &mut Buffer) {
let title = Title::from(" EthyleneAMD ".bold()).alignment(Alignment::Center);
let instructions = Title::from(Line::from(vec![
" <A> ".red(),
"Apply".into(),
" <Q> ".red(),
"Quit ".into(),
]))
.alignment(Alignment::Center)
.position(Position::Bottom);
let block = Block::bordered()
.title(title)
.title(instructions)
.border_type(ratatui::widgets::BorderType::Rounded);

self.render_list(block, area, buf);
}
}

impl App {
fn render_list(&mut self, block: Block<'_>, area: Rect, buf: &mut Buffer) {
let items: Vec<ListItem> = self
.app_list
.items
.iter()
.enumerate()
.map(|(i, app_item)| {
ListItem::from(format!(
"{}. {}",
i + 1,
app_item.name.clone()
+ (if self.app_list.selected_items.contains(&i) {
" <"
} else {
""
})
))
})
.collect();

let list = List::new(items)
.block(block)
.highlight_style(SELECTED_STYLE)
.highlight_symbol(">")
.highlight_spacing(ratatui::widgets::HighlightSpacing::Always);

StatefulWidget::render(list, area, buf, &mut self.app_list.state);
}
}

0 comments on commit a1f7e1a

Please sign in to comment.