2022-12-29 18:00:59 -08:00
|
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
|
|
|
|
use matrix_sdk::{
|
|
|
|
room::Room as MatrixRoom,
|
|
|
|
ruma::{OwnedRoomId, RoomId},
|
|
|
|
};
|
|
|
|
|
|
|
|
use modalkit::tui::{buffer::Buffer, layout::Rect, widgets::StatefulWidget};
|
|
|
|
|
|
|
|
use modalkit::{
|
|
|
|
widgets::list::{List, ListState},
|
|
|
|
widgets::{TermOffset, TerminalCursor, WindowOps},
|
|
|
|
};
|
|
|
|
|
|
|
|
use crate::base::{IambBufferId, IambInfo, ProgramStore, RoomFocus};
|
|
|
|
|
|
|
|
use crate::windows::RoomItem;
|
|
|
|
|
|
|
|
pub struct SpaceState {
|
|
|
|
room_id: OwnedRoomId,
|
2023-01-05 18:12:25 -08:00
|
|
|
room: MatrixRoom,
|
2022-12-29 18:00:59 -08:00
|
|
|
list: ListState<RoomItem, IambInfo>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SpaceState {
|
|
|
|
pub fn new(room: MatrixRoom) -> Self {
|
|
|
|
let room_id = room.room_id().to_owned();
|
|
|
|
let content = IambBufferId::Room(room_id.clone(), RoomFocus::Scrollback);
|
|
|
|
let list = ListState::new(content, vec![]);
|
|
|
|
|
2023-01-05 18:12:25 -08:00
|
|
|
SpaceState { room_id, room, list }
|
|
|
|
}
|
|
|
|
|
2023-01-11 17:54:49 -08:00
|
|
|
pub fn refresh_room(&mut self, store: &mut ProgramStore) {
|
|
|
|
if let Some(room) = store.application.worker.client.get_room(self.id()) {
|
|
|
|
self.room = room;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-05 18:12:25 -08:00
|
|
|
pub fn room(&self) -> &MatrixRoom {
|
|
|
|
&self.room
|
2022-12-29 18:00:59 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn id(&self) -> &RoomId {
|
|
|
|
&self.room_id
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn dup(&self, store: &mut ProgramStore) -> Self {
|
|
|
|
SpaceState {
|
|
|
|
room_id: self.room_id.clone(),
|
2023-01-05 18:12:25 -08:00
|
|
|
room: self.room.clone(),
|
2022-12-29 18:00:59 -08:00
|
|
|
list: self.list.dup(store),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TerminalCursor for SpaceState {
|
|
|
|
fn get_term_cursor(&self) -> Option<TermOffset> {
|
|
|
|
self.list.get_term_cursor()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Deref for SpaceState {
|
|
|
|
type Target = ListState<RoomItem, IambInfo>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.list
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DerefMut for SpaceState {
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
|
&mut self.list
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Space<'a> {
|
|
|
|
focused: bool,
|
|
|
|
store: &'a mut ProgramStore,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Space<'a> {
|
|
|
|
pub fn new(store: &'a mut ProgramStore) -> Self {
|
|
|
|
Space { focused: false, store }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn focus(mut self, focused: bool) -> Self {
|
|
|
|
self.focused = focused;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> StatefulWidget for Space<'a> {
|
|
|
|
type State = SpaceState;
|
|
|
|
|
|
|
|
fn render(self, area: Rect, buffer: &mut Buffer, state: &mut Self::State) {
|
2023-01-11 17:54:49 -08:00
|
|
|
let members =
|
|
|
|
if let Ok(m) = self.store.application.worker.space_members(state.room_id.clone()) {
|
|
|
|
m
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
2022-12-29 18:00:59 -08:00
|
|
|
let items = members
|
|
|
|
.into_iter()
|
|
|
|
.filter_map(|id| {
|
2023-01-25 17:54:16 -08:00
|
|
|
let (room, name, tags) = self.store.application.worker.get_room(id.clone()).ok()?;
|
2022-12-29 18:00:59 -08:00
|
|
|
|
|
|
|
if id != state.room_id {
|
2023-01-25 17:54:16 -08:00
|
|
|
Some(RoomItem::new(room, name, tags, self.store))
|
2022-12-29 18:00:59 -08:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
state.list.set(items);
|
|
|
|
|
|
|
|
List::new(self.store)
|
|
|
|
.focus(self.focused)
|
|
|
|
.render(area, buffer, &mut state.list)
|
|
|
|
}
|
|
|
|
}
|