Compare commits
6 Commits
c3a2b2d566
...
2a2c173683
Author | SHA1 | Date |
---|---|---|
Benedikt Peetz | 2a2c173683 | |
Benedikt Peetz | fbd1672d03 | |
Benedikt Peetz | 734328787e | |
Benedikt Peetz | 14333944dc | |
Benedikt Peetz | a413171ffe | |
Benedikt Peetz | 6412650686 |
|
@ -88,7 +88,7 @@ fn append_tx_send_code(input: &mut syn::ItemFn) -> &mut syn::ItemFn {
|
||||||
.expect("This is valid.");
|
.expect("This is valid.");
|
||||||
return_type_as_return_type
|
return_type_as_return_type
|
||||||
} else {
|
} else {
|
||||||
// There is only rlua
|
// There is only mlua::Error left
|
||||||
ReturnType::Default
|
ReturnType::Default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,23 +108,22 @@ fn append_tx_send_code(input: &mut syn::ItemFn) -> &mut syn::ItemFn {
|
||||||
ReturnType::Type(_, _) => {
|
ReturnType::Type(_, _) => {
|
||||||
quote! {
|
quote! {
|
||||||
{
|
{
|
||||||
Event::CommandEvent(Command::#function_name_pascal(input_str))
|
Event::CommandEvent(Command::#function_name_pascal(input_str.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
{
|
{
|
||||||
let tx: std::sync::Arc<std::sync::Mutex<tokio::sync::mpsc::Sender<crate::app::events::event_types::Event>>> =
|
let tx:
|
||||||
|
core::cell::Ref<
|
||||||
|
tokio::sync::mpsc::Sender<crate::app::events::event_types::Event>
|
||||||
|
> =
|
||||||
lua
|
lua
|
||||||
.named_registry_value("sender_for_ci_commands")
|
.app_data_ref()
|
||||||
.expect("This exists, it was set before");
|
.expect("This exists, it was set before");
|
||||||
|
|
||||||
tx
|
(*tx)
|
||||||
// FIXME: This is sync code, it needs to be run in a blocking allowed
|
|
||||||
// executor
|
|
||||||
.lock()
|
|
||||||
.expect("This should work, as only one function is executed. It wil however fail, when concurrency is added");
|
|
||||||
.send(#send_data)
|
.send(#send_data)
|
||||||
.await
|
.await
|
||||||
.expect("This should work, as the reciever is not dropped");
|
.expect("This should work, as the reciever is not dropped");
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub fn generate_generate_ci_function(input: &syn::DeriveInput) -> TokenStream2 {
|
||||||
lua: &mut mlua::Lua,
|
lua: &mut mlua::Lua,
|
||||||
tx: tokio::sync::mpsc::Sender<crate::app::events::event_types::Event>)
|
tx: tokio::sync::mpsc::Sender<crate::app::events::event_types::Event>)
|
||||||
{
|
{
|
||||||
lua.set_named_registry_value("sender_for_ci_commands", std::sync::Arc::new(std::sync::Mutex::new(tx))).expect("This should always work, as the value is added before all else");
|
lua.set_app_data(tx);
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
#input_tokens
|
#input_tokens
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// FIXME: This file needs documentation with examples of how the proc macros work.
|
// FIXME: This file needs documentation with examples of how the proc macros work.
|
||||||
// for now use `cargo expand app::command_interface` for an overview
|
// for now use `cargo expand app::command_interface` for an overview
|
||||||
use lua_macros::{ci_command, turn_struct_to_ci_commands};
|
use lua_macros::{ci_command, turn_struct_to_ci_commands};
|
||||||
use rlua::Context;
|
|
||||||
|
|
||||||
use super::events::event_types::Event;
|
use super::events::event_types::Event;
|
||||||
|
|
||||||
|
@ -23,22 +22,30 @@ use super::events::event_types::Event;
|
||||||
/// `String` and `()`).
|
/// `String` and `()`).
|
||||||
#[turn_struct_to_ci_commands]
|
#[turn_struct_to_ci_commands]
|
||||||
struct Commands {
|
struct Commands {
|
||||||
|
/// Greets the user
|
||||||
greet: fn(usize) -> String,
|
greet: fn(usize) -> String,
|
||||||
|
|
||||||
// Closes the application
|
/// Closes the application
|
||||||
#[gen_default_lua_function]
|
#[gen_default_lua_function]
|
||||||
exit: fn(),
|
exit: fn(),
|
||||||
|
|
||||||
|
/// Shows the command line
|
||||||
#[gen_default_lua_function]
|
#[gen_default_lua_function]
|
||||||
command_line_show: fn(),
|
command_line_show: fn(),
|
||||||
|
|
||||||
|
/// Hides the command line
|
||||||
#[gen_default_lua_function]
|
#[gen_default_lua_function]
|
||||||
command_line_hide: fn(),
|
command_line_hide: fn(),
|
||||||
|
|
||||||
|
/// Go to the next plane
|
||||||
#[gen_default_lua_function]
|
#[gen_default_lua_function]
|
||||||
cycle_planes: fn(),
|
cycle_planes: fn(),
|
||||||
|
/// Go to the previous plane
|
||||||
#[gen_default_lua_function]
|
#[gen_default_lua_function]
|
||||||
cycle_planes_rev: fn(),
|
cycle_planes_rev: fn(),
|
||||||
|
|
||||||
//// sends a message to the current room
|
/// Send a message to the current room
|
||||||
|
/// The send message is interpreted literally.
|
||||||
room_message_send: fn(String) -> String,
|
room_message_send: fn(String) -> String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::app::{events::event_types::EventStatus, App, command_interface::Command};
|
use crate::app::{command_interface::Command, events::event_types::EventStatus, App};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cli_log::info;
|
use cli_log::info;
|
||||||
|
|
||||||
|
@ -32,5 +32,9 @@ pub async fn handle(app: &mut App<'_>, command: &Command) -> Result<EventStatus>
|
||||||
}
|
}
|
||||||
EventStatus::Ok
|
EventStatus::Ok
|
||||||
}
|
}
|
||||||
|
Command::Greet(name) => {
|
||||||
|
info!("Greated {}", name);
|
||||||
|
EventStatus::Ok
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub async fn handle(app: &mut App<'_>, command: &str) -> Result<EventStatus> {
|
||||||
.with_context(|| format!("Failed to execute: `{command}`"))?;
|
.with_context(|| format!("Failed to execute: `{command}`"))?;
|
||||||
info!("Function evaluated to: `{output}`");
|
info!("Function evaluated to: `{output}`");
|
||||||
|
|
||||||
app.transmitter.send(Event::CiOutput(output));
|
app.tx.send(Event::CiOutput(output)).await.context("Failed to send ci output to internal event stream")?;
|
||||||
|
|
||||||
Ok(EventStatus::Ok)
|
Ok(EventStatus::Ok)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::Result;
|
use anyhow::{Context, Result};
|
||||||
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent, KeyModifiers};
|
use crossterm::event::{Event as CrosstermEvent, KeyCode, KeyEvent, KeyModifiers};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -15,14 +15,14 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
CrosstermEvent::Key(KeyEvent {
|
CrosstermEvent::Key(KeyEvent {
|
||||||
code: KeyCode::Esc, ..
|
code: KeyCode::Esc, ..
|
||||||
}) => {
|
}) => {
|
||||||
app.transmitter
|
app.tx
|
||||||
.send(Event::CommandEvent(Command::Exit))
|
.send(Event::CommandEvent(Command::Exit))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
CrosstermEvent::Key(KeyEvent {
|
CrosstermEvent::Key(KeyEvent {
|
||||||
code: KeyCode::Tab, ..
|
code: KeyCode::Tab, ..
|
||||||
}) => {
|
}) => {
|
||||||
app.transmitter
|
app.tx
|
||||||
.send(Event::CommandEvent(Command::CyclePlanes))
|
.send(Event::CommandEvent(Command::CyclePlanes))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
code: KeyCode::BackTab,
|
code: KeyCode::BackTab,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
app.transmitter
|
app.tx
|
||||||
.send(Event::CommandEvent(Command::CyclePlanesRev))
|
.send(Event::CommandEvent(Command::CyclePlanesRev))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
modifiers: KeyModifiers::CONTROL,
|
modifiers: KeyModifiers::CONTROL,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
app.transmitter
|
app.tx
|
||||||
.send(Event::CommandEvent(Command::CommandLineShow))
|
.send(Event::CommandEvent(Command::CommandLineShow))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
modifiers: KeyModifiers::ALT,
|
modifiers: KeyModifiers::ALT,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
app.transmitter
|
app.tx
|
||||||
.send(Event::CommandEvent(Command::RoomMessageSend(
|
.send(Event::CommandEvent(Command::RoomMessageSend(
|
||||||
app.ui.message_compose.lines().join("\n"),
|
app.ui.message_compose.lines().join("\n"),
|
||||||
)))
|
)))
|
||||||
|
@ -155,7 +155,7 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
code: KeyCode::Enter,
|
code: KeyCode::Enter,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let cli_event = app.ui
|
let ci_event = app.ui
|
||||||
.cli
|
.cli
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.expect("This is already checked")
|
.expect("This is already checked")
|
||||||
|
@ -165,16 +165,10 @@ pub async fn handle(app: &mut App<'_>, input_event: &CrosstermEvent) -> Result<E
|
||||||
"There can only be one line in the buffer, as we collect it on enter being inputted"
|
"There can only be one line in the buffer, as we collect it on enter being inputted"
|
||||||
)
|
)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
let output = app.handle_ci_event(&cli_event).await?;
|
app.tx
|
||||||
|
.send(Event::LuaCommand(ci_event))
|
||||||
// delete the old text:
|
.await
|
||||||
|
.context("Failed to send lua command to internal event stream")?;
|
||||||
// We can use a mutable borrow now, as we should only need one
|
|
||||||
let cli = app.ui.cli.as_mut().expect("Checked above");
|
|
||||||
cli.move_cursor(tui_textarea::CursorMove::Jump(0, 0));
|
|
||||||
cli.delete_str(0, cli_event.chars().count());
|
|
||||||
assert!(cli.is_empty());
|
|
||||||
cli.insert_str(output);
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
app.ui
|
app.ui
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
pub mod command;
|
// input events
|
||||||
pub mod main;
|
|
||||||
pub mod matrix;
|
|
||||||
pub mod setup;
|
pub mod setup;
|
||||||
|
pub mod main;
|
||||||
|
|
||||||
|
// matrix
|
||||||
|
pub mod matrix;
|
||||||
|
|
||||||
|
// ci
|
||||||
|
pub mod ci_output;
|
||||||
|
pub mod command;
|
||||||
|
pub mod lua_command;
|
||||||
|
|
|
@ -3,9 +3,9 @@ mod handlers;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use crossterm::event::Event as CrosstermEvent;
|
use crossterm::event::Event as CrosstermEvent;
|
||||||
|
|
||||||
use crate::app::{status::State, App, command_interface::Command};
|
use crate::app::{command_interface::Command, status::State, App};
|
||||||
|
|
||||||
use self::handlers::{command, main, matrix, setup};
|
use self::handlers::{ci_output, command, lua_command, main, matrix, setup};
|
||||||
|
|
||||||
use super::EventStatus;
|
use super::EventStatus;
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ pub enum Event {
|
||||||
InputEvent(CrosstermEvent),
|
InputEvent(CrosstermEvent),
|
||||||
MatrixEvent(matrix_sdk::deserialized_responses::SyncResponse),
|
MatrixEvent(matrix_sdk::deserialized_responses::SyncResponse),
|
||||||
CommandEvent(Command),
|
CommandEvent(Command),
|
||||||
|
CiOutput(String),
|
||||||
|
LuaCommand(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event {
|
impl Event {
|
||||||
|
@ -26,6 +28,14 @@ impl Event {
|
||||||
Event::CommandEvent(event) => command::handle(app, event)
|
Event::CommandEvent(event) => command::handle(app, event)
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("Failed to handle command event: `{:#?}`", event)),
|
.with_context(|| format!("Failed to handle command event: `{:#?}`", event)),
|
||||||
|
Event::CiOutput(output) => ci_output::handle(app, output).await.with_context(|| {
|
||||||
|
format!("Failed to handle command interface output: `{:#?}`", output)
|
||||||
|
}),
|
||||||
|
Event::LuaCommand(lua_code) => {
|
||||||
|
lua_command::handle(app, lua_code).await.with_context(|| {
|
||||||
|
format!("Failed to handle lua code: `{:#?}`", lua_code)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
Event::InputEvent(event) => match app.status.state() {
|
Event::InputEvent(event) => match app.status.state() {
|
||||||
State::None => Ok(EventStatus::Ok),
|
State::None => Ok(EventStatus::Ok),
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
pub mod command_interface;
|
pub mod command_interface;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
pub mod transmitter;
|
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::{Context, Error, Result};
|
use anyhow::{Error, Result, Context};
|
||||||
use cli_log::info;
|
use cli_log::info;
|
||||||
use matrix_sdk::Client;
|
use matrix_sdk::Client;
|
||||||
use mlua::Lua;
|
use mlua::Lua;
|
||||||
|
@ -19,14 +18,16 @@ use crate::{
|
||||||
ui::{central, setup},
|
ui::{central, setup},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{events::event_types, transmitter::Transmitter};
|
use self::events::event_types;
|
||||||
|
|
||||||
pub struct App<'ui> {
|
pub struct App<'ui> {
|
||||||
ui: central::UI<'ui>,
|
ui: central::UI<'ui>,
|
||||||
accounts_manager: AccountsManager,
|
accounts_manager: AccountsManager,
|
||||||
status: Status,
|
status: Status,
|
||||||
|
|
||||||
transmitter: Transmitter,
|
tx: mpsc::Sender<Event>,
|
||||||
|
rx: mpsc::Receiver<Event>,
|
||||||
|
|
||||||
input_listener_killer: CancellationToken,
|
input_listener_killer: CancellationToken,
|
||||||
matrix_listener_killer: CancellationToken,
|
matrix_listener_killer: CancellationToken,
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ pub struct App<'ui> {
|
||||||
impl App<'_> {
|
impl App<'_> {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
fn set_up_lua(tx: mpsc::Sender<Event>) -> Lua {
|
fn set_up_lua(tx: mpsc::Sender<Event>) -> Lua {
|
||||||
let lua = Lua::new();
|
let mut lua = Lua::new();
|
||||||
|
|
||||||
generate_ci_functions(&mut lua, tx);
|
generate_ci_functions(&mut lua, tx);
|
||||||
lua
|
lua
|
||||||
|
@ -50,39 +51,25 @@ impl App<'_> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let transmitter = Transmitter::new();
|
let (tx, rx) = mpsc::channel(256);
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ui: central::UI::new()?,
|
ui: central::UI::new()?,
|
||||||
accounts_manager: AccountsManager::new(config)?,
|
accounts_manager: AccountsManager::new(config)?,
|
||||||
status: Status::new(None),
|
status: Status::new(None),
|
||||||
|
|
||||||
transmitter,
|
tx: tx.clone(),
|
||||||
|
rx,
|
||||||
input_listener_killer: CancellationToken::new(),
|
input_listener_killer: CancellationToken::new(),
|
||||||
matrix_listener_killer: CancellationToken::new(),
|
matrix_listener_killer: CancellationToken::new(),
|
||||||
|
|
||||||
lua: set_up_lua(transmitter.tx()),
|
lua: set_up_lua(tx),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_ci_event(&self, event: &str) -> Result<String> {
|
|
||||||
info!("Recieved ci event: `{event}`; executing..");
|
|
||||||
|
|
||||||
// TODO: Should the ci support more than strings?
|
|
||||||
let output = self.lua.context(|context| -> Result<String> {
|
|
||||||
let output = context
|
|
||||||
.load(&event)
|
|
||||||
.eval::<String>()
|
|
||||||
.with_context(|| format!("Failed to execute: `{event}`"))?;
|
|
||||||
info!("Function evaluated to: `{output}`");
|
|
||||||
Ok(output)
|
|
||||||
})?;
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run(&mut self) -> Result<()> {
|
pub async fn run(&mut self) -> Result<()> {
|
||||||
// Spawn input event listener
|
// Spawn input event listener
|
||||||
tokio::task::spawn(events::poll_input_events(
|
tokio::task::spawn(events::poll_input_events(
|
||||||
self.transmitter.tx(),
|
self.tx.clone(),
|
||||||
self.input_listener_killer.clone(),
|
self.input_listener_killer.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -98,11 +85,7 @@ impl App<'_> {
|
||||||
self.status.set_state(State::Main);
|
self.status.set_state(State::Main);
|
||||||
self.ui.update(&self.status).await?;
|
self.ui.update(&self.status).await?;
|
||||||
|
|
||||||
let event = self
|
let event = self.rx.recv().await.context("Failed to get next event")?;
|
||||||
.transmitter
|
|
||||||
.recv()
|
|
||||||
.await
|
|
||||||
.context("Failed to get next event")?;
|
|
||||||
|
|
||||||
match event.handle(self).await? {
|
match event.handle(self).await? {
|
||||||
event_types::EventStatus::Ok => (),
|
event_types::EventStatus::Ok => (),
|
||||||
|
@ -122,11 +105,7 @@ impl App<'_> {
|
||||||
self.status.set_state(State::Setup);
|
self.status.set_state(State::Setup);
|
||||||
self.ui.update_setup().await?;
|
self.ui.update_setup().await?;
|
||||||
|
|
||||||
let event = self
|
let event = self.rx.recv().await.context("Failed to get next event")?;
|
||||||
.transmitter
|
|
||||||
.recv()
|
|
||||||
.await
|
|
||||||
.context("Failed to get next event")?;
|
|
||||||
|
|
||||||
match event.handle(self).await? {
|
match event.handle(self).await? {
|
||||||
event_types::EventStatus::Ok => (),
|
event_types::EventStatus::Ok => (),
|
||||||
|
@ -150,7 +129,7 @@ impl App<'_> {
|
||||||
|
|
||||||
// Spawn Matrix Event Listener
|
// Spawn Matrix Event Listener
|
||||||
tokio::task::spawn(events::poll_matrix_events(
|
tokio::task::spawn(events::poll_matrix_events(
|
||||||
self.transmitter.tx(),
|
self.tx.clone(),
|
||||||
self.matrix_listener_killer.clone(),
|
self.matrix_listener_killer.clone(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
));
|
));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::{Error, Result};
|
use anyhow::{Error, Result};
|
||||||
use cli_log::{warn, info};
|
use cli_log::warn;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
room::MessagesOptions,
|
room::MessagesOptions,
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
use anyhow::{bail, Context, Result};
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
|
|
||||||
use super::events::event_types::Event;
|
|
||||||
|
|
||||||
pub struct Transmitter {
|
|
||||||
tx: mpsc::Sender<Event>,
|
|
||||||
rx: mpsc::Receiver<Event>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Transmitter {
|
|
||||||
pub fn new() -> Transmitter {
|
|
||||||
let (tx, rx) = mpsc::channel(256);
|
|
||||||
Transmitter {
|
|
||||||
tx,
|
|
||||||
rx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn tx(&self) -> mpsc::Sender<Event> {
|
|
||||||
self.tx.to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn recv(&mut self) -> Result<Event> {
|
|
||||||
match self.rx.recv().await {
|
|
||||||
Some(event) => Ok(event),
|
|
||||||
None => bail!("Event channel has no senders"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub async fn send(&mut self, event: Event) -> Result<()> {
|
|
||||||
self.tx.send(event).await.context("Failed to send event")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,8 +2,8 @@ pub mod update;
|
||||||
|
|
||||||
use std::io::Stdout;
|
use std::io::Stdout;
|
||||||
|
|
||||||
use anyhow::{bail, Result, Context};
|
use anyhow::{bail, Context, Result};
|
||||||
use cli_log::info;
|
use cli_log::{info, warn};
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::DisableMouseCapture,
|
event::DisableMouseCapture,
|
||||||
execute,
|
execute,
|
||||||
|
@ -125,6 +125,16 @@ impl UI<'_> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_command_output(&mut self, output: &str) {
|
||||||
|
info!("Setting output to: `{}`", output);
|
||||||
|
if let Some(_) = self.cli {
|
||||||
|
let cli = Some(TextArea::from([output]));
|
||||||
|
self.cli = cli;
|
||||||
|
} else {
|
||||||
|
warn!("Failed to set output");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cli_enable(&mut self) {
|
pub fn cli_enable(&mut self) {
|
||||||
self.input_position = InputPosition::CLI;
|
self.input_position = InputPosition::CLI;
|
||||||
if self.cli.is_some() {
|
if self.cli.is_some() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use tui::{
|
||||||
|
|
||||||
use crate::{app::status::Room, ui::central::InputPosition};
|
use crate::{app::status::Room, ui::central::InputPosition};
|
||||||
|
|
||||||
pub fn init<'a>(room: Option<&Room>, colors: &Vec<Color>) -> Result<(List<'a>, ListState)> {
|
pub fn init<'a>(room: Option<&'a Room>, colors: &Vec<Color>) -> Result<(List<'a>, ListState)> {
|
||||||
let content = match room {
|
let content = match room {
|
||||||
Some(room) => get_content_from_room(room).context("Failed to get content from room")?,
|
Some(room) => get_content_from_room(room).context("Failed to get content from room")?,
|
||||||
None => vec![ListItem::new(Text::styled(
|
None => vec![ListItem::new(Text::styled(
|
||||||
|
|
|
@ -6,7 +6,7 @@ use tui::{
|
||||||
|
|
||||||
use crate::{app::status::Room, ui::central::InputPosition};
|
use crate::{app::status::Room, ui::central::InputPosition};
|
||||||
|
|
||||||
pub fn init<'a>(room: Option<&Room>, colors: &Vec<Color>) -> Paragraph<'a> {
|
pub fn init<'a>(room: Option<&'a Room>, colors: &Vec<Color>) -> Paragraph<'a> {
|
||||||
let mut room_info_content = Text::default();
|
let mut room_info_content = Text::default();
|
||||||
if let Some(room) = room {
|
if let Some(room) = room {
|
||||||
room_info_content.extend(Text::styled(room.name(), Style::default().fg(Color::Cyan)));
|
room_info_content.extend(Text::styled(room.name(), Style::default().fg(Color::Cyan)));
|
||||||
|
|
|
@ -6,7 +6,7 @@ use tui::{
|
||||||
|
|
||||||
use crate::{app::status::Status, ui::central::InputPosition};
|
use crate::{app::status::Status, ui::central::InputPosition};
|
||||||
|
|
||||||
pub fn init<'a>(status: &Status, colors: &Vec<Color>) -> List<'a> {
|
pub fn init<'a>(status: &'a Status, colors: &Vec<Color>) -> List<'a> {
|
||||||
let rooms_content: Vec<_> = status
|
let rooms_content: Vec<_> = status
|
||||||
.rooms()
|
.rooms()
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -7,7 +7,7 @@ use tui::{
|
||||||
|
|
||||||
use crate::{app::status::Status, ui::central::InputPosition};
|
use crate::{app::status::Status, ui::central::InputPosition};
|
||||||
|
|
||||||
pub fn init<'a>(status: &Status, colors: &Vec<Color>) -> Paragraph<'a> {
|
pub fn init<'a>(status: &'a Status, colors: &Vec<Color>) -> Paragraph<'a> {
|
||||||
let mut status_content = Text::styled(
|
let mut status_content = Text::styled(
|
||||||
status.account_name(),
|
status.account_name(),
|
||||||
Style::default().add_modifier(Modifier::BOLD),
|
Style::default().add_modifier(Modifier::BOLD),
|
||||||
|
|
Reference in New Issue