Skip to content

Commit 2d89d6b

Browse files
committed
Use display name for mention completion
1 parent 4f9a308 commit 2d89d6b

File tree

3 files changed

+66
-15
lines changed

3 files changed

+66
-15
lines changed

src/base.rs

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,9 @@ pub struct RoomInfo {
914914
/// The display names for users in this room.
915915
pub display_names: HashMap<OwnedUserId, String>,
916916

917+
/// Tab completion for the display names in this room.
918+
pub display_name_completion: CompletionMap<String, OwnedUserId>,
919+
917920
/// The last time the room was rendered, used to detect if it is currently open.
918921
pub draw_last: Option<Instant>,
919922
}
@@ -935,6 +938,7 @@ impl Default for RoomInfo {
935938
fetch_last: Default::default(),
936939
users_typing: Default::default(),
937940
display_names: Default::default(),
941+
display_name_completion: Default::default(),
938942
draw_last: Default::default(),
939943
}
940944
}
@@ -1960,7 +1964,9 @@ impl Completer<IambInfo> for IambCompleter {
19601964
match content {
19611965
IambBufferId::Command(CommandType::Command) => complete_cmdbar(text, cursor, store),
19621966
IambBufferId::Command(CommandType::Search) => vec![],
1963-
IambBufferId::Room(_, _, RoomFocus::MessageBar) => complete_msgbar(text, cursor, store),
1967+
IambBufferId::Room(room_id, _, RoomFocus::MessageBar) => {
1968+
complete_msgbar(text, cursor, store, room_id)
1969+
},
19641970
IambBufferId::Room(_, _, RoomFocus::Scrollback) => vec![],
19651971

19661972
IambBufferId::DirectList => vec![],
@@ -1991,12 +1997,19 @@ fn complete_users(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Ve
19911997
}
19921998

19931999
/// Tab completion within the message bar.
1994-
fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Vec<String> {
2000+
fn complete_msgbar(
2001+
text: &EditRope,
2002+
cursor: &mut Cursor,
2003+
store: &mut ChatStore,
2004+
room_id: &RoomId,
2005+
) -> Vec<String> {
19952006
let id = text
19962007
.get_prefix_word_mut(cursor, &MATRIX_ID_WORD)
19972008
.unwrap_or_else(EditRope::empty);
19982009
let id = Cow::from(&id);
19992010

2011+
let info = store.rooms.get_or_default(room_id.to_owned());
2012+
20002013
match id.chars().next() {
20012014
// Complete room aliases.
20022015
Some('#') => {
@@ -2028,12 +2041,29 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> V
20282041

20292042
// Complete usernames for @ and empty strings.
20302043
Some('@') | None => {
2031-
store
2032-
.presences
2033-
.complete(id.as_ref())
2044+
// spec says to mention with display name in anchor text
2045+
let mut users: HashSet<_> = info
2046+
.display_name_completion
2047+
.complete(id.strip_prefix('@').unwrap())
20342048
.into_iter()
2035-
.map(|i| format!("[{}]({})", i, i.matrix_to_uri()))
2036-
.collect()
2049+
.map(|n| {
2050+
format!(
2051+
"[{}]({})",
2052+
n,
2053+
info.display_name_completion.get(&n).unwrap().matrix_to_uri()
2054+
)
2055+
})
2056+
.collect();
2057+
2058+
users.extend(store.presences.complete(id.as_ref()).into_iter().map(|i| {
2059+
format!(
2060+
"[{}]({})",
2061+
info.display_names.get(&i).unwrap_or(&i.to_string()),
2062+
i.matrix_to_uri()
2063+
)
2064+
}));
2065+
2066+
users.into_iter().collect()
20372067
},
20382068

20392069
// Unknown sigil.
@@ -2314,23 +2344,30 @@ pub mod tests {
23142344
#[tokio::test]
23152345
async fn test_complete_msgbar() {
23162346
let store = mock_store().await;
2317-
let store = store.application;
2347+
let mut store = store.application;
2348+
let room_id = TEST_ROOM1_ID.clone();
23182349

23192350
let text = EditRope::from("going for a walk :walk ");
23202351
let mut cursor = Cursor::new(0, 22);
2321-
let res = complete_msgbar(&text, &mut cursor, &store);
2352+
let res = complete_msgbar(&text, &mut cursor, &mut store, &room_id);
23222353
assert_eq!(res, vec![":walking:", ":walking_man:", ":walking_woman:"]);
23232354
assert_eq!(cursor, Cursor::new(0, 17));
23242355

23252356
let text = EditRope::from("hello @user1 ");
23262357
let mut cursor = Cursor::new(0, 12);
2327-
let res = complete_msgbar(&text, &mut cursor, &store);
2358+
let res = complete_msgbar(&text, &mut cursor, &mut store, &room_id);
23282359
assert_eq!(res, vec!["[@user1:example.com](https://matrix.to/#/@user1:example.com)"]);
23292360
assert_eq!(cursor, Cursor::new(0, 6));
23302361

2362+
let text = EditRope::from("hello @user2 ");
2363+
let mut cursor = Cursor::new(0, 12);
2364+
let res = complete_msgbar(&text, &mut cursor, &mut store, &room_id);
2365+
assert_eq!(res, vec!["[User 2](https://matrix.to/#/@user2:example.com)"]);
2366+
assert_eq!(cursor, Cursor::new(0, 6));
2367+
23312368
let text = EditRope::from("see #room ");
23322369
let mut cursor = Cursor::new(0, 9);
2333-
let res = complete_msgbar(&text, &mut cursor, &store);
2370+
let res = complete_msgbar(&text, &mut cursor, &mut store, &room_id);
23342371
assert_eq!(res, vec!["[#room1:example.com](https://matrix.to/#/%23room1:example.com)"]);
23352372
assert_eq!(cursor, Cursor::new(0, 4));
23362373
}

src/tests.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ pub fn mock_room() -> RoomInfo {
154154
room.name = Some("Watercooler Discussion".into());
155155
room.keys = mock_keys();
156156
*room.get_thread_mut(None) = mock_messages();
157+
158+
let user_id = TEST_USER2.clone();
159+
let name = "User 2";
160+
room.display_names.insert(user_id.clone(), name.to_string());
161+
room.display_name_completion.insert(name.to_string(), user_id.clone());
162+
157163
room
158164
}
159165

src/worker.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,8 @@ fn members_insert(
424424
let user_id = member.user_id();
425425
let display_name =
426426
member.display_name().map_or(user_id.to_string(), |str| str.to_string());
427-
info.display_names.insert(user_id.to_owned(), display_name);
427+
info.display_names.insert(user_id.to_owned(), display_name.clone());
428+
info.display_name_completion.insert(display_name, user_id.to_owned());
428429
}
429430
}
430431
// else ???
@@ -1136,11 +1137,18 @@ impl ClientWorker {
11361137
let info = locked.application.get_room_info(room_id.to_owned());
11371138

11381139
if ambiguous {
1139-
info.display_names.remove(&user_id);
1140+
let old_name = info.display_names.remove(&user_id);
1141+
if let Some(old_name) = old_name {
1142+
info.display_name_completion.remove(&old_name);
1143+
}
11401144
} else if let Some(display) = ev.content.displayname {
1141-
info.display_names.insert(user_id, display);
1145+
info.display_names.insert(user_id.clone(), display.clone());
1146+
info.display_name_completion.insert(display, user_id);
11421147
} else {
1143-
info.display_names.remove(&user_id);
1148+
let old_name = info.display_names.remove(&user_id);
1149+
if let Some(old_name) = old_name {
1150+
info.display_name_completion.remove(&old_name);
1151+
}
11441152
}
11451153
}
11461154
},

0 commit comments

Comments
 (0)