Skip to content

Commit

Permalink
Fix not showing display names in already synced rooms (#171)
Browse files Browse the repository at this point in the history
Fixes #149
  • Loading branch information
benjajaja committed Dec 19, 2023
1 parent b33759c commit 999399a
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 80 deletions.
55 changes: 49 additions & 6 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! The types defined here get used throughout iamb.
use std::borrow::Cow;
use std::collections::hash_map::IntoIter;
use std::collections::{HashMap, HashSet};
use std::convert::TryFrom;
use std::fmt::{self, Display};
Expand Down Expand Up @@ -1042,6 +1043,38 @@ pub struct SyncInfo {
pub dms: Vec<Arc<(MatrixRoom, Option<Tags>)>>,
}

bitflags::bitflags! {
/// Load-needs
#[derive(Debug, Default, PartialEq)]
pub struct Need: u32 {
const EMPTY = 0b00000000;
const MESSAGES = 0b00000001;
const MEMBERS = 0b00000010;
}
}

/// Things that need loading for different rooms.
#[derive(Default)]
pub struct RoomNeeds {
needs: HashMap<OwnedRoomId, Need>,
}

impl RoomNeeds {
/// Mark a room for needing something to be loaded.
pub fn insert(&mut self, room_id: OwnedRoomId, need: Need) {
self.needs.entry(room_id).or_default().insert(need);
}
}

impl IntoIterator for RoomNeeds {
type Item = (OwnedRoomId, Need);
type IntoIter = IntoIter<OwnedRoomId, Need>;

fn into_iter(self) -> Self::IntoIter {
self.needs.into_iter()
}
}

/// The main application state.
pub struct ChatStore {
/// `:`-commands
Expand All @@ -1066,7 +1099,7 @@ pub struct ChatStore {
pub settings: ApplicationSettings,

/// Set of rooms that need more messages loaded in their scrollback.
pub need_load: HashSet<OwnedRoomId>,
pub need_load: RoomNeeds,

/// [CompletionMap] of Emoji shortcodes.
pub emojis: CompletionMap<String, &'static Emoji>,
Expand Down Expand Up @@ -1113,11 +1146,6 @@ impl ChatStore {
.unwrap_or_else(|| "Untitled Matrix Room".to_string())
}

/// Mark a room for loading more scrollback.
pub fn mark_for_load(&mut self, room_id: OwnedRoomId) {
self.need_load.insert(room_id);
}

/// Get the [RoomInfo] for a given room identifier.
pub fn get_room_info(&mut self, room_id: OwnedRoomId) -> &mut RoomInfo {
self.rooms.get_or_default(room_id)
Expand Down Expand Up @@ -1659,6 +1687,21 @@ pub mod tests {
);
}

#[test]
fn test_need_load() {
let room_id = TEST_ROOM1_ID.clone();

let mut need_load = RoomNeeds::default();

need_load.insert(room_id.clone(), Need::MESSAGES);
need_load.insert(room_id.clone(), Need::MEMBERS);

assert_eq!(need_load.into_iter().collect::<Vec<(OwnedRoomId, Need)>>(), vec![(
room_id,
Need::MESSAGES | Need::MEMBERS,
)],);
}

#[tokio::test]
async fn test_complete_msgbar() {
let store = mock_store().await;
Expand Down
3 changes: 3 additions & 0 deletions src/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ use crate::base::{
IambInfo,
IambResult,
MessageAction,
Need,
ProgramAction,
ProgramContext,
ProgramStore,
Expand Down Expand Up @@ -659,6 +660,7 @@ impl Window<IambInfo> for IambWindow {
let (room, name, tags) = store.application.worker.get_room(room_id)?;
let room = RoomState::new(room, name, tags, store);

store.application.need_load.insert(room.id().to_owned(), Need::MEMBERS);
return Ok(room.into());
},
IambId::DirectList => {
Expand Down Expand Up @@ -710,6 +712,7 @@ impl Window<IambInfo> for IambWindow {
let (room, name, tags) = store.application.worker.get_room(room_id)?;
let room = RoomState::new(room, name, tags, store);

store.application.need_load.insert(room.id().to_owned(), Need::MEMBERS);
Ok(room.into())
}
}
Expand Down
87 changes: 53 additions & 34 deletions src/windows/room/scrollback.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Message scrollback
use std::collections::HashSet;

use ratatui_image::FixedImage;
use regex::Regex;
Expand Down Expand Up @@ -73,7 +72,16 @@ use modalkit::editing::{
};

use crate::{
base::{IambBufferId, IambInfo, IambResult, ProgramContext, ProgramStore, RoomFocus, RoomInfo},
base::{
IambBufferId,
IambInfo,
IambResult,
Need,
ProgramContext,
ProgramStore,
RoomFocus,
RoomInfo,
},
config::ApplicationSettings,
message::{Message, MessageCursor, MessageKey, Messages},
};
Expand Down Expand Up @@ -468,8 +476,7 @@ impl ScrollbackState {
needle: &Regex,
mut count: usize,
info: &RoomInfo,
need_load: &mut HashSet<OwnedRoomId>,
) -> Option<MessageCursor> {
) -> (Option<MessageCursor>, bool) {
let mut mc = None;

for (key, msg) in info.messages.range(..&end).rev() {
Expand All @@ -483,11 +490,7 @@ impl ScrollbackState {
}
}

if count > 0 {
need_load.insert(self.room_id.clone());
}

return mc;
return (mc, count > 0);
}

fn find_message(
Expand All @@ -497,11 +500,10 @@ impl ScrollbackState {
needle: &Regex,
count: usize,
info: &RoomInfo,
need_load: &mut HashSet<OwnedRoomId>,
) -> Option<MessageCursor> {
) -> (Option<MessageCursor>, bool) {
match dir {
MoveDir1D::Next => self.find_message_next(key, needle, count, info),
MoveDir1D::Previous => self.find_message_prev(key, needle, count, info, need_load),
MoveDir1D::Next => (self.find_message_next(key, needle, count, info), false),
MoveDir1D::Previous => self.find_message_prev(key, needle, count, info),
}
}
}
Expand Down Expand Up @@ -628,14 +630,14 @@ impl EditorActions<ProgramContext, ProgramStore, IambInfo> for ScrollbackState {
},
};

self.find_message(
key,
dir,
&needle,
count,
info,
&mut store.application.need_load,
)
let (mc, needs_load) = self.find_message(key, dir, &needle, count, info);
if needs_load {
store
.application
.need_load
.insert(self.room_id.clone(), Need::MESSAGES);
}
mc
},
EditTarget::Search(SearchType::Word(_, _), _, _) => {
let msg = "Cannot perform word search in a list";
Expand Down Expand Up @@ -714,15 +716,15 @@ impl EditorActions<ProgramContext, ProgramStore, IambInfo> for ScrollbackState {
},
};

self.find_message(
key,
dir,
&needle,
count,
info,
&mut store.application.need_load,
)
.map(|c| self._range_to(c))
let (mc, needs_load) = self.find_message(key, dir, &needle, count, info);
if needs_load {
store
.application
.need_load
.insert(self.room_id.to_owned(), Need::MESSAGES);
}

mc.map(|c| self._range_to(c))
},
EditTarget::Search(SearchType::Word(_, _), _, _) => {
let msg = "Cannot perform word search in a list";
Expand Down Expand Up @@ -1288,7 +1290,10 @@ impl<'a> StatefulWidget for Scrollback<'a> {
let cursor_key = if let Some(k) = cursor.to_key(info) {
k
} else {
self.store.application.mark_for_load(state.room_id.clone());
self.store
.application
.need_load
.insert(state.room_id.to_owned(), Need::MESSAGES);
return;
};

Expand Down Expand Up @@ -1389,7 +1394,10 @@ impl<'a> StatefulWidget for Scrollback<'a> {
let first_key = info.messages.first_key_value().map(|(k, _)| k.clone());
if first_key == state.viewctx.corner.timestamp {
// If the top of the screen is the older message, load more.
self.store.application.mark_for_load(state.room_id.clone());
self.store
.application
.need_load
.insert(state.room_id.to_owned(), Need::MESSAGES);
}
}
}
Expand Down Expand Up @@ -1427,12 +1435,23 @@ mod tests {
// Search backwards to MSG2.
scrollback.search(prev.clone(), 1.into(), &ctx, &mut store).unwrap();
assert_eq!(scrollback.cursor, MSG2_KEY.clone().into());
assert_eq!(store.application.need_load.contains(&room_id), false);
assert_eq!(
std::mem::take(&mut store.application.need_load)
.into_iter()
.collect::<Vec<(OwnedRoomId, Need)>>()
.is_empty(),
true,
);

// Can't go any further; need_load now contains the room ID.
scrollback.search(prev.clone(), 1.into(), &ctx, &mut store).unwrap();
assert_eq!(scrollback.cursor, MSG2_KEY.clone().into());
assert_eq!(store.application.need_load.contains(&room_id), true);
assert_eq!(
std::mem::take(&mut store.application.need_load)
.into_iter()
.collect::<Vec<(OwnedRoomId, Need)>>(),
vec![(room_id.clone(), Need::MESSAGES)]
);

// Search forward twice to MSG1.
scrollback.search(next.clone(), 2.into(), &ctx, &mut store).unwrap();
Expand Down

0 comments on commit 999399a

Please sign in to comment.