Improve README

This commit is contained in:
Erik Kundt
2024-05-21 17:30:30 +02:00
parent b0e32a7d4e
commit 369616abd1
3 changed files with 94 additions and 44 deletions
+92 -43
View File
@@ -1,8 +1,16 @@
# radicle-tui
_Radicle terminal user interfaces_
![alt text](demo.gif "Demo")
## Installation
`radicle-tui` provides various terminal user interfaces for interacting with the [Radicle](https://radicle.xyz) code forge and exposes the application framework they were built with.
## Binaries
This crate provides a single binary called `rad-tui`, which contains all user interfaces. Specific interfaces can be run by the appropriate command, e.g. `rad-tui patch select` shows a patch selector.
The interfaces are designed to be modular and to integrate well with the existing Radicle CLI. Right now, they are meant to be called from other programs that will collect and process their output.
### Installation
**Requirements**
@@ -10,87 +18,128 @@ _Radicle terminal user interfaces_
- Git 2.34 or later
- OpenSSH 9.1 or later with `ssh-agent`
### 📦 From source
#### From source
> Requires the Rust toolchain.
You can install the binary from source, by running the following
commands from inside this repository:
cargo install --path . --force --locked
```
cargo install --path . --force --locked
```
Or directly from our seed node:
cargo install --force --locked --git https://seed.radicle.xyz/z39mP9rQAaGmERfUMPULfPUi473tY.git
```
cargo install --force --locked --git https://seed.radicle.xyz/z39mP9rQAaGmERfUMPULfPUi473tY.git
```
This will install `rad-tui`. You can execute it by running `rad-tui`. All available commands can be shown by running `rad-tui --help`.
## Interfaces
The Radicle terminal interfaces are designed to be modular and to integrate well with the existing Radicle CLI. Right now, they are meant to be called from other programs that will collect and process their output.
### Usage
#### Patches
Select a patch and an operation:
$ rad-tui patch select
{ "operation": "show", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
Select a patch, an issue or a notification and an operation:
```
$ rad-tui <patch | issue | inbox> select
```
Same as above:
$ rad-tui patch select --mode operation
{ "operation": "show", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
```
$ rad-tui <patch | issue | inbox> select --mode operation
```
Select a patch only and return its id:
Select a patch, an issue or a notification only and return its id:
$ rad-tui patch select --mode id
{ "operation": "null", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
```
$ rad-tui <patch | issue | inbox> select --mode id
```
#### Issues
### Output
Select an issue and an operation:
All interfaces return a JSON object that reflects the choices made by the user, e.g.:
$ rad-tui issue select
{ "operation": "show", "ids": ["12f019e3f9f52d88b470a3d7fb922452ebaca39e"], args:[] }
```
{ "operation": "show", "ids": ["546443226b300484a97a2b2d7c7000af6e8169ba"], args:[] }
```
## Framework
Same as above:
The library portion of this crate is a framework that is the foundation for the interfaces mentioned above. The framework is built on top of [ratatui](https://ratatui.rs) and was inspired by the Flux application pattern. It took some ideas from [cursive](https://github.com/gyscos/cursive) and [rust-chat-server](https://github.com/Yengas/rust-chat-server).
$ rad-tui issue select --mode operation
{ "operation": "show", "ids": ["12f019e3f9f52d88b470a3d7fb922452ebaca39e"], args:[] }
### Example
```rust
use anyhow::Result;
use termion::event::Key;
Select an issue only and return its id:
use radicle_tui as tui;
$ rad-tui issue select --mode id
{ "operation": "null", "ids": ["12f019e3f9f52d88b470a3d7fb922452ebaca39e"], args:[] }
use tui::store;
use tui::ui::widget::text::{Paragraph, ParagraphProps};
use tui::ui::widget::{Properties, Widget};
use tui::{Channel, Exit};
#[derive(Clone, Debug)]
struct State {
welcome: String,
}
#### Inbox
enum Message {
Quit,
ReverseWelcome,
}
Select a notification and an operation:
impl store::State<()> for State {
type Message = Message;
$ rad-tui inbox select
{ "operation": "show", "ids": ["1"], args:[] }
fn update(&mut self, message: Self::Message) -> Option<tui::Exit<()>> {
match message {
Message::Quit => Some(Exit { value: None }),
Message::ReverseWelcome => {
self.welcome = self.welcome.chars().rev().collect::<String>();
None
}
}
}
fn tick(&self) {}
}
Same as above:
#[tokio::main]
pub async fn main() -> Result<()> {
let channel = Channel::default();
let state = State {
welcome: "Hello TUI".to_string(),
};
$ rad-tui inbox select --mode operation
{ "operation": "show", "ids": ["1"], args:[] }
let welcome = Paragraph::new(&state, channel.tx.clone())
.on_update(|state| {
ParagraphProps::default()
.text(&state.welcome.clone().into())
.to_boxed()
})
.on_event(|paragraph, key| {
paragraph
.downcast_mut::<Paragraph<'_, State, Message>>()
.and_then(|paragraph| match key {
Key::Char('r') => paragraph.send(Message::ReverseWelcome).ok(),
Key::Char('q') => paragraph.send(Message::Quit).ok(),
_ => None,
});
})
.to_boxed();
tui::run(channel, state, welcome).await?;
Select a notification only and return its id:
$ rad-tui inbox select --mode id
{ "operation": "null", "ids": ["1"], args:[] }
Ok(())
}
```
## License
Radicle is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
`radicle-tui` is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 862 KiB

+2 -1
View File
@@ -95,7 +95,8 @@ impl<W: Write> ratatui::backend::Backend for TermionBackendExt<W> {
pub fn setup(height: usize) -> anyhow::Result<Terminal<Backend>> {
let stdout = io::stdout().into_raw_mode()?;
let options = TerminalOptions {
viewport: Viewport::Inline(height as u16),
// viewport: Viewport::Inline(height as u16),
viewport: Viewport::Fullscreen,
};
Ok(Terminal::with_options(