mirror of
https://github.com/youwen5/iamb.git
synced 2025-08-04 19:48:28 -07:00
Support displaying and editing room descriptions (#12)
This commit is contained in:
parent
8ed037afca
commit
38f4795886
13 changed files with 286 additions and 55 deletions
|
@ -13,7 +13,7 @@ use modalkit::tui::{
|
|||
layout::{Alignment, Rect},
|
||||
style::{Modifier as StyleModifier, Style},
|
||||
text::{Span, Spans, Text},
|
||||
widgets::{Block, Borders, StatefulWidget, Widget},
|
||||
widgets::StatefulWidget,
|
||||
};
|
||||
|
||||
use modalkit::{
|
||||
|
@ -71,6 +71,21 @@ use self::{room::RoomState, welcome::WelcomeState};
|
|||
pub mod room;
|
||||
pub mod welcome;
|
||||
|
||||
#[inline]
|
||||
fn bold_style() -> Style {
|
||||
Style::default().add_modifier(StyleModifier::BOLD)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bold_span(s: &str) -> Span {
|
||||
Span::styled(s, bold_style())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bold_spans(s: &str) -> Spans {
|
||||
bold_span(s).into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn selected_style(selected: bool) -> Style {
|
||||
if selected {
|
||||
|
@ -168,22 +183,6 @@ impl IambWindow {
|
|||
return Err(err);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_title(&self, store: &mut ProgramStore) -> String {
|
||||
match self {
|
||||
IambWindow::DirectList(_) => "Direct Messages".to_string(),
|
||||
IambWindow::RoomList(_) => "Rooms".to_string(),
|
||||
IambWindow::SpaceList(_) => "Spaces".to_string(),
|
||||
IambWindow::VerifyList(_) => "Verifications".to_string(),
|
||||
IambWindow::Welcome(_) => "Welcome to iamb".to_string(),
|
||||
|
||||
IambWindow::Room(w) => w.get_title(store),
|
||||
IambWindow::MemberList(_, room_id) => {
|
||||
let title = store.application.get_room_title(room_id.as_ref());
|
||||
format!("Room Members: {}", title)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type DirectListState = ListState<DirectItem, IambInfo>;
|
||||
|
@ -281,13 +280,8 @@ impl TerminalCursor for IambWindow {
|
|||
|
||||
impl WindowOps<IambInfo> for IambWindow {
|
||||
fn draw(&mut self, area: Rect, buf: &mut Buffer, focused: bool, store: &mut ProgramStore) {
|
||||
let title = self.get_title(store);
|
||||
let block = Block::default().title(title.as_str()).borders(Borders::ALL);
|
||||
let inner = block.inner(area);
|
||||
block.render(area, buf);
|
||||
|
||||
match self {
|
||||
IambWindow::Room(state) => state.draw(inner, buf, focused, store),
|
||||
IambWindow::Room(state) => state.draw(area, buf, focused, store),
|
||||
IambWindow::DirectList(state) => {
|
||||
let dms = store.application.worker.direct_messages();
|
||||
let items = dms.into_iter().map(|(id, name)| DirectItem::new(id, name, store));
|
||||
|
@ -297,7 +291,7 @@ impl WindowOps<IambInfo> for IambWindow {
|
|||
.empty_message("No direct messages yet!")
|
||||
.empty_alignment(Alignment::Center)
|
||||
.focus(focused)
|
||||
.render(inner, buf, state);
|
||||
.render(area, buf, state);
|
||||
},
|
||||
IambWindow::MemberList(state, room_id) => {
|
||||
if let Ok(mems) = store.application.worker.members(room_id.clone()) {
|
||||
|
@ -309,7 +303,7 @@ impl WindowOps<IambInfo> for IambWindow {
|
|||
.empty_message("No users here yet!")
|
||||
.empty_alignment(Alignment::Center)
|
||||
.focus(focused)
|
||||
.render(inner, buf, state);
|
||||
.render(area, buf, state);
|
||||
},
|
||||
IambWindow::RoomList(state) => {
|
||||
let joined = store.application.worker.joined_rooms();
|
||||
|
@ -320,20 +314,20 @@ impl WindowOps<IambInfo> for IambWindow {
|
|||
.empty_message("You haven't joined any rooms yet")
|
||||
.empty_alignment(Alignment::Center)
|
||||
.focus(focused)
|
||||
.render(inner, buf, state);
|
||||
.render(area, buf, state);
|
||||
},
|
||||
IambWindow::SpaceList(state) => {
|
||||
let spaces = store.application.worker.spaces();
|
||||
let items =
|
||||
spaces.into_iter().map(|(room, name)| SpaceItem::new(room, name, store));
|
||||
state.set(items.collect());
|
||||
state.draw(inner, buf, focused, store);
|
||||
state.draw(area, buf, focused, store);
|
||||
|
||||
List::new(store)
|
||||
.empty_message("You haven't joined any spaces yet")
|
||||
.empty_alignment(Alignment::Center)
|
||||
.focus(focused)
|
||||
.render(inner, buf, state);
|
||||
.render(area, buf, state);
|
||||
},
|
||||
IambWindow::VerifyList(state) => {
|
||||
let verifications = &store.application.verifications;
|
||||
|
@ -348,9 +342,9 @@ impl WindowOps<IambInfo> for IambWindow {
|
|||
.empty_message("No in-progress verifications")
|
||||
.empty_alignment(Alignment::Center)
|
||||
.focus(focused)
|
||||
.render(inner, buf, state);
|
||||
.render(area, buf, state);
|
||||
},
|
||||
IambWindow::Welcome(state) => state.draw(inner, buf, focused, store),
|
||||
IambWindow::Welcome(state) => state.draw(area, buf, focused, store),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,6 +388,44 @@ impl Window<IambInfo> for IambWindow {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_tab_title(&self, store: &mut ProgramStore) -> Spans {
|
||||
match self {
|
||||
IambWindow::DirectList(_) => bold_spans("Direct Messages"),
|
||||
IambWindow::RoomList(_) => bold_spans("Rooms"),
|
||||
IambWindow::SpaceList(_) => bold_spans("Spaces"),
|
||||
IambWindow::VerifyList(_) => bold_spans("Verifications"),
|
||||
IambWindow::Welcome(_) => bold_spans("Welcome to iamb"),
|
||||
|
||||
IambWindow::Room(w) => {
|
||||
let title = store.application.get_room_title(w.id());
|
||||
|
||||
Spans::from(title)
|
||||
},
|
||||
IambWindow::MemberList(_, room_id) => {
|
||||
let title = store.application.get_room_title(room_id.as_ref());
|
||||
|
||||
Spans(vec![bold_span("Room Members: "), title.into()])
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_win_title(&self, store: &mut ProgramStore) -> Spans {
|
||||
match self {
|
||||
IambWindow::DirectList(_) => bold_spans("Direct Messages"),
|
||||
IambWindow::RoomList(_) => bold_spans("Rooms"),
|
||||
IambWindow::SpaceList(_) => bold_spans("Spaces"),
|
||||
IambWindow::VerifyList(_) => bold_spans("Verifications"),
|
||||
IambWindow::Welcome(_) => bold_spans("Welcome to iamb"),
|
||||
|
||||
IambWindow::Room(w) => w.get_title(store),
|
||||
IambWindow::MemberList(_, room_id) => {
|
||||
let title = store.application.get_room_title(room_id.as_ref());
|
||||
|
||||
Spans(vec![bold_span("Room Members: "), title.into()])
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn open(id: IambId, store: &mut ProgramStore) -> IambResult<Self> {
|
||||
match id {
|
||||
IambId::Room(room_id) => {
|
||||
|
@ -464,6 +496,10 @@ impl Window<IambInfo> for IambWindow {
|
|||
|
||||
Err(err)
|
||||
}
|
||||
|
||||
fn unnamed(store: &mut ProgramStore) -> IambResult<Self> {
|
||||
Self::open(IambId::RoomList, store)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
@ -44,6 +44,7 @@ use super::scrollback::{Scrollback, ScrollbackState};
|
|||
|
||||
pub struct ChatState {
|
||||
room_id: OwnedRoomId,
|
||||
room: MatrixRoom,
|
||||
|
||||
tbox: TextBoxState<IambInfo>,
|
||||
sent: HistoryList<EditRope>,
|
||||
|
@ -63,6 +64,7 @@ impl ChatState {
|
|||
|
||||
ChatState {
|
||||
room_id,
|
||||
room,
|
||||
|
||||
tbox,
|
||||
sent: HistoryList::new(EditRope::from(""), 100),
|
||||
|
@ -80,6 +82,10 @@ impl ChatState {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn room(&self) -> &MatrixRoom {
|
||||
&self.room
|
||||
}
|
||||
|
||||
pub fn id(&self) -> &RoomId {
|
||||
&self.room_id
|
||||
}
|
||||
|
@ -133,6 +139,7 @@ impl WindowOps<IambInfo> for ChatState {
|
|||
|
||||
ChatState {
|
||||
room_id: self.room_id.clone(),
|
||||
room: self.room.clone(),
|
||||
|
||||
tbox,
|
||||
sent: self.sent.clone(),
|
||||
|
|
|
@ -2,7 +2,13 @@ use matrix_sdk::room::Room as MatrixRoom;
|
|||
use matrix_sdk::ruma::RoomId;
|
||||
use matrix_sdk::DisplayName;
|
||||
|
||||
use modalkit::tui::{buffer::Buffer, layout::Rect, widgets::StatefulWidget};
|
||||
use modalkit::tui::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Modifier as StyleModifier, Style},
|
||||
text::{Span, Spans},
|
||||
widgets::StatefulWidget,
|
||||
};
|
||||
|
||||
use modalkit::{
|
||||
editing::action::{
|
||||
|
@ -90,7 +96,7 @@ impl RoomState {
|
|||
&mut self,
|
||||
act: RoomAction,
|
||||
_: ProgramContext,
|
||||
_: &mut ProgramStore,
|
||||
store: &mut ProgramStore,
|
||||
) -> IambResult<Vec<(Action<IambInfo>, ProgramContext)>> {
|
||||
match act {
|
||||
RoomAction::Members(mut cmd) => {
|
||||
|
@ -103,11 +109,29 @@ impl RoomState {
|
|||
|
||||
Ok(vec![(act, cmd.context.take())])
|
||||
},
|
||||
RoomAction::Set(field) => {
|
||||
store.application.worker.set_room(self.id().to_owned(), field)?;
|
||||
|
||||
Ok(vec![])
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_title(&self, store: &mut ProgramStore) -> String {
|
||||
store.application.get_room_title(self.id())
|
||||
pub fn get_title(&self, store: &mut ProgramStore) -> Spans {
|
||||
let title = store.application.get_room_title(self.id());
|
||||
let style = Style::default().add_modifier(StyleModifier::BOLD);
|
||||
let mut spans = vec![Span::styled(title, style)];
|
||||
|
||||
match self.room().topic() {
|
||||
Some(desc) if !desc.is_empty() => {
|
||||
spans.push(" (".into());
|
||||
spans.push(desc.into());
|
||||
spans.push(")".into());
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
Spans(spans)
|
||||
}
|
||||
|
||||
pub fn focus_toggle(&mut self) {
|
||||
|
@ -117,6 +141,13 @@ impl RoomState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn room(&self) -> &MatrixRoom {
|
||||
match self {
|
||||
RoomState::Chat(chat) => chat.room(),
|
||||
RoomState::Space(space) => space.room(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn id(&self) -> &RoomId {
|
||||
match self {
|
||||
RoomState::Chat(chat) => chat.id(),
|
||||
|
|
|
@ -18,6 +18,7 @@ use crate::windows::RoomItem;
|
|||
|
||||
pub struct SpaceState {
|
||||
room_id: OwnedRoomId,
|
||||
room: MatrixRoom,
|
||||
list: ListState<RoomItem, IambInfo>,
|
||||
}
|
||||
|
||||
|
@ -27,7 +28,11 @@ impl SpaceState {
|
|||
let content = IambBufferId::Room(room_id.clone(), RoomFocus::Scrollback);
|
||||
let list = ListState::new(content, vec![]);
|
||||
|
||||
SpaceState { room_id, list }
|
||||
SpaceState { room_id, room, list }
|
||||
}
|
||||
|
||||
pub fn room(&self) -> &MatrixRoom {
|
||||
&self.room
|
||||
}
|
||||
|
||||
pub fn id(&self) -> &RoomId {
|
||||
|
@ -37,6 +42,7 @@ impl SpaceState {
|
|||
pub fn dup(&self, store: &mut ProgramStore) -> Self {
|
||||
SpaceState {
|
||||
room_id: self.room_id.clone(),
|
||||
room: self.room.clone(),
|
||||
list: self.list.dup(store),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue