Skip to content

Commit

Permalink
feat(ui): about plugin and release notes (#3979)
Browse files Browse the repository at this point in the history
* basic about screen

* work

* finish implementing about plugin except theme spec

* show about plugin only on first version run

* some cleanups and do the right thing with open/xdg-open

* refactor: make ui framework

* refactor: remove old stuff

* refactor: about plugin

* style(fmt): rustfmt

* chore(repo): about plugin asset

* fix tests

* style(fmt): rustfmt!!
  • Loading branch information
imsnif authored Feb 10, 2025
1 parent fc847b7 commit 3e493f3
Show file tree
Hide file tree
Showing 31 changed files with 1,509 additions and 10 deletions.
11 changes: 10 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ members = [
"default-plugins/session-manager",
"default-plugins/configuration",
"default-plugins/plugin-manager",
"default-plugins/about",
"zellij-client",
"zellij-server",
"zellij-utils",
Expand Down
2 changes: 2 additions & 0 deletions default-plugins/about/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
target = "wasm32-wasip1"
1 change: 1 addition & 0 deletions default-plugins/about/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
11 changes: 11 additions & 0 deletions default-plugins/about/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "about"
version = "0.1.0"
authors = ["Aram Drevekenin <[email protected]>"]
edition = "2021"
license = "MIT"

[dependencies]
ansi_term = "0.12.1"
zellij-tile = { path = "../../zellij-tile" }
chrono = "0.4.0"
1 change: 1 addition & 0 deletions default-plugins/about/LICENSE.md
151 changes: 151 additions & 0 deletions default-plugins/about/src/active_component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
use std::cell::RefCell;
use std::rc::Rc;
use zellij_tile::prelude::*;

use crate::pages::{Page, TextOrCustomRender};

#[derive(Debug)]
pub struct ActiveComponent {
text_no_hover: TextOrCustomRender,
text_hover: Option<TextOrCustomRender>,
left_click_action: Option<ClickAction>,
last_rendered_coordinates: Option<ComponentCoordinates>,
pub is_active: bool,
}

impl ActiveComponent {
pub fn new(text_no_hover: TextOrCustomRender) -> Self {
ActiveComponent {
text_no_hover,
text_hover: None,
left_click_action: None,
is_active: false,
last_rendered_coordinates: None,
}
}
pub fn with_hover(mut self, text_hover: TextOrCustomRender) -> Self {
self.text_hover = Some(text_hover);
self
}
pub fn with_left_click_action(mut self, left_click_action: ClickAction) -> Self {
self.left_click_action = Some(left_click_action);
self
}
pub fn render(&mut self, x: usize, y: usize, rows: usize, columns: usize) -> usize {
let mut component_width = 0;
match self.text_hover.as_mut() {
Some(text) if self.is_active => {
let text_len = text.render(x, y, rows, columns);
component_width += text_len;
},
_ => {
let text_len = self.text_no_hover.render(x, y, rows, columns);
component_width += text_len;
},
}
self.last_rendered_coordinates = Some(ComponentCoordinates::new(x, y, 1, columns));
component_width
}
pub fn left_click_action(&mut self) -> Option<Page> {
match self.left_click_action.take() {
Some(ClickAction::ChangePage(go_to_page)) => Some(go_to_page()),
Some(ClickAction::OpenLink(link, executable)) => {
self.left_click_action =
Some(ClickAction::OpenLink(link.clone(), executable.clone()));
run_command(&[&executable.borrow(), &link], Default::default());
None
},
None => None,
}
}
pub fn handle_left_click_at_position(&mut self, x: usize, y: usize) -> Option<Page> {
let Some(last_rendered_coordinates) = &self.last_rendered_coordinates else {
return None;
};
if last_rendered_coordinates.contains(x, y) {
self.left_click_action()
} else {
None
}
}
pub fn handle_hover_at_position(&mut self, x: usize, y: usize) -> bool {
let Some(last_rendered_coordinates) = &self.last_rendered_coordinates else {
return false;
};
if last_rendered_coordinates.contains(x, y) && self.text_hover.is_some() {
self.is_active = true;
true
} else {
false
}
}
pub fn handle_selection(&mut self) -> Option<Page> {
if self.is_active {
self.left_click_action()
} else {
None
}
}
pub fn column_count(&self) -> usize {
match self.text_hover.as_ref() {
Some(text) if self.is_active => text.len(),
_ => self.text_no_hover.len(),
}
}
pub fn clear_hover(&mut self) {
self.is_active = false;
}
}

#[derive(Debug)]
struct ComponentCoordinates {
x: usize,
y: usize,
rows: usize,
columns: usize,
}

impl ComponentCoordinates {
pub fn contains(&self, x: usize, y: usize) -> bool {
x >= self.x && x < self.x + self.columns && y >= self.y && y < self.y + self.rows
}
}

impl ComponentCoordinates {
pub fn new(x: usize, y: usize, rows: usize, columns: usize) -> Self {
ComponentCoordinates {
x,
y,
rows,
columns,
}
}
}

pub enum ClickAction {
ChangePage(Box<dyn FnOnce() -> Page>),
OpenLink(String, Rc<RefCell<String>>), // (destination, executable)
}

impl std::fmt::Debug for ClickAction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ClickAction::ChangePage(_) => write!(f, "ChangePage"),
ClickAction::OpenLink(destination, executable) => {
write!(f, "OpenLink: {}, {:?}", destination, executable)
},
}
}
}

impl ClickAction {
pub fn new_change_page<F>(go_to_page: F) -> Self
where
F: FnOnce() -> Page + 'static,
{
ClickAction::ChangePage(Box::new(go_to_page))
}
pub fn new_open_link(destination: String, executable: Rc<RefCell<String>>) -> Self {
ClickAction::OpenLink(destination, executable)
}
}
Loading

0 comments on commit 3e493f3

Please sign in to comment.