feature (UI - main): started work on timeline view implementation
This commit is contained in:
parent
a7e11c6ac0
commit
1eb04dd23a
|
@ -55,7 +55,7 @@ impl App<'_> {
|
||||||
Self {
|
Self {
|
||||||
ui: ui::UI::new(),
|
ui: ui::UI::new(),
|
||||||
accounts_manager: AccountsManager::new(config),
|
accounts_manager: AccountsManager::new(config),
|
||||||
status: Status::default(),
|
status: Status::new(None),
|
||||||
|
|
||||||
channel_tx,
|
channel_tx,
|
||||||
channel_rx,
|
channel_rx,
|
||||||
|
@ -124,12 +124,14 @@ impl App<'_> {
|
||||||
None => return Err(Error::msg("failed to get current client"))
|
None => return Err(Error::msg("failed to get current client"))
|
||||||
}.clone();
|
}.clone();
|
||||||
|
|
||||||
if !self.matrix_listener_killer.is_cancelled() {
|
|
||||||
self.matrix_listener_killer.cancel();
|
self.matrix_listener_killer.cancel();
|
||||||
self.matrix_listener_killer = CancellationToken::new();
|
self.matrix_listener_killer = CancellationToken::new();
|
||||||
}
|
|
||||||
|
|
||||||
tokio::task::spawn(event::poll_matrix_events(self.channel_tx.clone(), self.matrix_listener_killer.clone(), client));
|
// Spawn Matrix Event Listener
|
||||||
|
tokio::task::spawn(event::poll_matrix_events(self.channel_tx.clone(), self.matrix_listener_killer.clone(), client.clone()));
|
||||||
|
|
||||||
|
// Reset Status
|
||||||
|
self.status = Status::new(Some(client));
|
||||||
|
|
||||||
let account = self.account()?;
|
let account = self.account()?;
|
||||||
let name = account.name().clone();
|
let name = account.name().clone();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use matrix_sdk::Client;
|
||||||
|
use matrix_sdk::ruma::{room_id, RoomId, ServerName};
|
||||||
|
|
||||||
pub enum State {
|
pub enum State {
|
||||||
None,
|
None,
|
||||||
|
@ -9,21 +11,29 @@ pub struct Status {
|
||||||
state: State,
|
state: State,
|
||||||
account_name: String,
|
account_name: String,
|
||||||
account_user_id: String,
|
account_user_id: String,
|
||||||
current_room_id: u32,
|
|
||||||
|
client: Option<Client>,
|
||||||
|
rooms: Vec<matrix_sdk::room::Joined>,
|
||||||
|
current_room_id: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Status {
|
impl Status {
|
||||||
fn default() -> Self {
|
pub fn new(client: Option<Client>) -> Self {
|
||||||
|
let rooms = match &client {
|
||||||
|
Some(c) => c.joined_rooms(),
|
||||||
|
None => Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
state: State::None,
|
state: State::None,
|
||||||
account_name: "".to_string(),
|
account_name: "".to_string(),
|
||||||
account_user_id: "".to_string(),
|
account_user_id: "".to_string(),
|
||||||
current_room_id: 0,
|
client,
|
||||||
}
|
rooms,
|
||||||
|
current_room_id: Some(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Status {
|
|
||||||
pub fn account_name(&self) -> &String {
|
pub fn account_name(&self) -> &String {
|
||||||
&self.account_name
|
&self.account_name
|
||||||
}
|
}
|
||||||
|
@ -40,8 +50,8 @@ impl Status {
|
||||||
self.account_user_id = user_id;
|
self.account_user_id = user_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn room(&self) -> Option<()> {
|
pub fn room(&self) -> Option<&matrix_sdk::room::Joined> {
|
||||||
None
|
self.rooms.get(self.current_room_id? as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state(&self) -> &State {
|
pub fn state(&self) -> &State {
|
||||||
|
|
|
@ -17,6 +17,7 @@ use tui::text::{Spans, Span, Text};
|
||||||
use tui::widgets::{Paragraph, Wrap};
|
use tui::widgets::{Paragraph, Wrap};
|
||||||
use tui_textarea::{Input, Key, TextArea};
|
use tui_textarea::{Input, Key, TextArea};
|
||||||
use cli_log::{error, warn, info};
|
use cli_log::{error, warn, info};
|
||||||
|
use matrix_sdk::{room::MessagesOptions, ruma::events::{AnyTimelineEvent, AnyMessageLikeEvent}};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum SetupInputPosition {
|
pub enum SetupInputPosition {
|
||||||
|
@ -248,9 +249,7 @@ impl UI<'_> {
|
||||||
|
|
||||||
pub fn input_position(&self) -> &MainInputPosition { &self.input_position }
|
pub fn input_position(&self) -> &MainInputPosition { &self.input_position }
|
||||||
|
|
||||||
pub async fn update(&'_ mut self, status: &Status) -> Result<()> {
|
pub async fn update(&mut self, status: &Status) -> Result<()> {
|
||||||
// TODO: make thread safe
|
|
||||||
|
|
||||||
let chunk = self.terminal.size()?;
|
let chunk = self.terminal.size()?;
|
||||||
|
|
||||||
let main_chunks = Layout::default()
|
let main_chunks = Layout::default()
|
||||||
|
@ -277,23 +276,59 @@ impl UI<'_> {
|
||||||
status_content.extend(Text::styled(status.account_user_id(), Style::default()));
|
status_content.extend(Text::styled(status.account_user_id(), Style::default()));
|
||||||
status_content.extend(Text::styled("settings", Style::default().fg(Color::LightMagenta).add_modifier(Modifier::ITALIC | Modifier::UNDERLINED)));
|
status_content.extend(Text::styled("settings", Style::default().fg(Color::LightMagenta).add_modifier(Modifier::ITALIC | Modifier::UNDERLINED)));
|
||||||
|
|
||||||
|
let messages_config = MessagesOptions::backward();
|
||||||
|
|
||||||
let messages_content = match status.room() {
|
let messages_content = match status.room() {
|
||||||
_ => {
|
Some(r) => {
|
||||||
|
r.messages(messages_config)
|
||||||
|
.await?
|
||||||
|
.chunk
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.map(|event| {
|
||||||
|
match event.event.deserialize() {
|
||||||
|
Ok(timeline_event) => match timeline_event {
|
||||||
|
|
||||||
|
// Message Like Events
|
||||||
|
AnyTimelineEvent::MessageLike(message_like_event) => {
|
||||||
|
let (content, color) = match &message_like_event {
|
||||||
|
AnyMessageLikeEvent::RoomMessage(room_message_event) => {
|
||||||
|
let message_content = &room_message_event
|
||||||
|
.as_original()
|
||||||
|
.unwrap()
|
||||||
|
.content
|
||||||
|
.body();
|
||||||
|
|
||||||
|
(message_content.to_string(), Color::White)
|
||||||
|
},
|
||||||
|
_ => ("~~~ not supported message like event ~~~".to_string(), Color::Red)
|
||||||
|
};
|
||||||
|
Spans::from(vec![
|
||||||
|
Span::styled(message_like_event.sender().to_string(), Style::default().fg(Color::Cyan)),
|
||||||
|
Span::styled(": ", Style::default().fg(Color::Cyan)),
|
||||||
|
Span::styled(content, Style::default().fg(color)),
|
||||||
|
])
|
||||||
|
},
|
||||||
|
|
||||||
|
// State Events
|
||||||
|
AnyTimelineEvent::State(state) => {
|
||||||
|
Spans::from(vec![
|
||||||
|
Span::styled(state.sender().to_string(), Style::default().fg(Color::DarkGray)),
|
||||||
|
Span::styled(": ", Style::default().fg(Color::DarkGray)),
|
||||||
|
Span::styled(state.event_type().to_string(), Style::default().fg(Color::DarkGray))
|
||||||
|
])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => Spans::from(
|
||||||
|
Span::styled("Failed to deserialize event", Style::default().fg(Color::Red))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
},
|
||||||
|
None => {
|
||||||
vec![Spans::from(Span::styled("No room selected!", Style::default().fg(Color::Magenta)))]
|
vec![Spans::from(Span::styled("No room selected!", Style::default().fg(Color::Magenta)))]
|
||||||
},
|
},
|
||||||
// Some(r) => {
|
|
||||||
// r.messages
|
|
||||||
// .iter()
|
|
||||||
// .rev()
|
|
||||||
// .map(|msg| {
|
|
||||||
// Spans::from(vec![
|
|
||||||
// Span::styled(&msg.author, Style::default().fg(Color::Cyan)),
|
|
||||||
// Span::styled(": ", Style::default().fg(Color::Cyan)),
|
|
||||||
// Span::styled(&msg.message, Style::default().fg(Color::White)),
|
|
||||||
// ])
|
|
||||||
// })
|
|
||||||
// .collect::<Vec<_>>()
|
|
||||||
// },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// calculate to widgets colors, based of which widget is currently selected
|
// calculate to widgets colors, based of which widget is currently selected
|
||||||
|
|
Reference in New Issue