This repository has been archived on 2024-05-26. You can view files and clone it, but cannot push or open issues or pull requests.
core/src/app/status.rs

214 lines
5.4 KiB
Rust
Raw Normal View History

use std::any::Any;
use anyhow::{Error, Result};
use cli_log::{error, info, warn};
use indexmap::IndexMap;
use matrix_sdk::{
room::MessagesOptions,
ruma::{
events::{room::message::RoomMessageEventContent, AnyTimelineEvent, StateEventType},
RoomId, TransactionId,
},
Client,
};
pub enum State {
None,
Main,
Setup,
}
pub struct Room {
matrix_room: matrix_sdk::room::Joined,
name: String,
encrypted: bool,
timeline: Vec<AnyTimelineEvent>,
timeline_end: Option<String>,
view_scroll: Option<usize>,
}
pub struct Status {
state: State,
account_name: String,
account_user_id: String,
client: Option<Client>,
rooms: IndexMap<String, Room>,
current_room_id: String,
}
impl Room {
pub fn new(matrix_room: matrix_sdk::room::Joined) -> Self {
Self {
matrix_room,
name: "".to_string(),
encrypted: false,
timeline: Vec::new(),
timeline_end: None,
view_scroll: None,
}
}
pub async fn poll_old_timeline(&mut self) -> Result<()> {
if let Some(AnyTimelineEvent::State(event)) = &self.timeline.get(0) {
if event.event_type() == StateEventType::RoomCreate {
return Ok(());
}
}
let mut messages_options = MessagesOptions::backward();
messages_options = match &self.timeline_end {
Some(end) => messages_options.from(end.as_str()),
None => messages_options,
};
let events = self.matrix_room.messages(messages_options).await?;
self.timeline_end = events.end;
for event in events.chunk.iter() {
self.timeline.insert(
0,
match event.event.deserialize() {
Ok(ev) => ev,
Err(err) => {
warn!("Failed to deserialize timeline event - {err}");
continue;
}
},
);
}
Ok(())
}
pub fn name(&self) -> &String {
&self.name
}
pub async fn update_name(&mut self) -> Result<()> {
self.name = self.matrix_room.display_name().await?.to_string();
Ok(())
}
pub fn timeline_add(&mut self, event: AnyTimelineEvent) {
self.timeline.push(event);
}
pub fn timeline(&self) -> &Vec<AnyTimelineEvent> {
&self.timeline
}
pub async fn send(&mut self, message: String) -> Result<()> {
let content = RoomMessageEventContent::text_plain(message);
let id = TransactionId::new();
self.matrix_room.send(content, Some(&id)).await?;
Ok(())
}
pub fn view_scroll(&self) -> Option<usize> {
self.view_scroll
}
pub fn set_view_scroll(&mut self, scroll: Option<usize>) {
self.view_scroll = scroll;
}
pub fn encrypted(&self) -> bool {
self.matrix_room.is_encrypted()
}
}
impl Status {
pub fn new(client: Option<Client>) -> Self {
let mut rooms = IndexMap::new();
if let Some(c) = &client {
for r in c.joined_rooms() {
rooms.insert(r.room_id().to_string(), Room::new(r.clone()));
}
};
Self {
state: State::None,
account_name: "".to_string(),
account_user_id: "".to_string(),
client,
rooms,
current_room_id: "".to_string(),
}
}
pub fn account_name(&self) -> &String {
&self.account_name
}
pub fn set_account_name(&mut self, name: String) {
self.account_name = name;
}
pub fn account_user_id(&self) -> &String {
&self.account_user_id
}
pub fn set_account_user_id(&mut self, user_id: String) {
self.account_user_id = user_id;
}
pub fn room(&self) -> Option<&Room> {
self.rooms.get(self.current_room_id.as_str())
}
pub fn room_mut(&mut self) -> Option<&mut Room> {
self.rooms.get_mut(self.current_room_id.as_str())
}
pub fn rooms(&self) -> &IndexMap<String, Room> {
&self.rooms
}
pub fn rooms_mut(&mut self) -> &mut IndexMap<String, Room> {
&mut self.rooms
}
pub fn set_room(&mut self, room_id: &RoomId) -> Result<()> {
if self.rooms.contains_key(room_id.as_str()) {
self.current_room_id = room_id.to_string();
Ok(())
} else {
Err(Error::msg(format!(
"failed to set room -> invalid room id {}",
room_id.to_string()
)))
}
}
pub fn set_room_by_index(&mut self, room_index: usize) -> Result<()> {
if let Some((room_id, _)) = self.rooms.get_index(room_index) {
self.current_room_id = room_id.clone();
Ok(())
} else {
Err(Error::msg(format!(
"failed to set room -> invalid room index {}",
room_index
)))
}
}
pub fn get_room(&self, room_id: &RoomId) -> Option<&Room> {
self.rooms.get(room_id.as_str())
}
pub fn get_room_mut(&mut self, room_id: &RoomId) -> Option<&mut Room> {
self.rooms.get_mut(room_id.as_str())
}
pub fn state(&self) -> &State {
&self.state
}
pub fn set_state(&mut self, state: State) {
self.state = state;
}
pub fn cli_event(&mut self, event: String) {
info!("CLI Event: {}", event);
}
}