forked from trinitrix/core
1
0
Fork 0

feature (UI - main): started work on timeline view implementation

This commit is contained in:
antifallobst 2023-07-06 20:47:06 +02:00
parent a7e11c6ac0
commit 1eb04dd23a
3 changed files with 78 additions and 31 deletions

View File

@ -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();

View File

@ -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 {

View File

@ -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