room: implement room_name according to spec, add RoomSummary to RoomName
This commit is contained in:
parent
bd3b0e7b74
commit
ebe4f03c36
3 changed files with 45 additions and 20 deletions
|
@ -561,7 +561,7 @@ impl AsyncClient {
|
|||
let mut response = self.send(request).await?;
|
||||
|
||||
for (room_id, room) in &mut response.rooms.join {
|
||||
let _matrix_room = {
|
||||
let matrix_room = {
|
||||
let mut client = self.base_client.write().await;
|
||||
for event in &room.state.events {
|
||||
if let EventResult::Ok(e) = event {
|
||||
|
@ -572,6 +572,9 @@ impl AsyncClient {
|
|||
client.get_or_create_room(&room_id).clone()
|
||||
};
|
||||
|
||||
// RoomSummary contains information for calculating room name
|
||||
matrix_room.write().await.set_room_summary(&room.summary);
|
||||
|
||||
// re looping is not ideal here
|
||||
for event in &mut room.state.events {
|
||||
if let EventResult::Ok(e) = event {
|
||||
|
|
|
@ -26,6 +26,7 @@ use crate::api::r0 as api;
|
|||
use crate::error::Result;
|
||||
use crate::events::collections::all::{RoomEvent, StateEvent};
|
||||
use crate::events::presence::PresenceEvent;
|
||||
use api::sync::sync_events::RoomSummary;
|
||||
// `NonRoomEvent` is what it is aliased as
|
||||
use crate::events::collections::only::Event as NonRoomEvent;
|
||||
use crate::events::ignored_user_list::IgnoredUserListEvent;
|
||||
|
@ -160,7 +161,7 @@ impl Client {
|
|||
pub(crate) async fn calculate_room_name(&self, room_id: &RoomId) -> Option<String> {
|
||||
if let Some(room) = self.joined_rooms.get(room_id) {
|
||||
let room = room.read().await;
|
||||
Some(room.room_name.calculate_name(room_id, &room.members))
|
||||
Some(room.room_name.calculate_name(&room.members))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -168,9 +169,9 @@ impl Client {
|
|||
|
||||
pub(crate) async fn calculate_room_names(&self) -> Vec<String> {
|
||||
let mut res = Vec::new();
|
||||
for (id, room) in &self.joined_rooms {
|
||||
for (_id, room) in &self.joined_rooms {
|
||||
let room = room.read().await;
|
||||
res.push(room.room_name.calculate_name(id, &room.members))
|
||||
res.push(room.room_name.calculate_name(&room.members))
|
||||
}
|
||||
res
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use std::convert::TryFrom;
|
|||
|
||||
use super::RoomMember;
|
||||
|
||||
use crate::api::r0::sync::sync_events::RoomSummary;
|
||||
use crate::events::collections::all::{RoomEvent, StateEvent};
|
||||
use crate::events::presence::PresenceEvent;
|
||||
use crate::events::room::{
|
||||
|
@ -42,6 +43,17 @@ pub struct RoomName {
|
|||
canonical_alias: Option<RoomAliasId>,
|
||||
/// List of `RoomAliasId`s the room has been given.
|
||||
aliases: Vec<RoomAliasId>,
|
||||
/// Users which can be used to generate a room name if the room does not have
|
||||
/// one. Required if room name or canonical aliases are not set or empty.
|
||||
pub heroes: Vec<String>,
|
||||
/// Number of users whose membership status is `join`.
|
||||
/// Required if field has changed since last sync; otherwise, it may be
|
||||
/// omitted.
|
||||
pub joined_member_count: Option<UInt>,
|
||||
/// Number of users whose membership status is `invite`.
|
||||
/// Required if field has changed since last sync; otherwise, it may be
|
||||
/// omitted.
|
||||
pub invited_member_count: Option<UInt>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
@ -112,11 +124,7 @@ impl RoomName {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn calculate_name(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
members: &HashMap<UserId, RoomMember>,
|
||||
) -> String {
|
||||
pub fn calculate_name(&self, members: &HashMap<UserId, RoomMember>) -> String {
|
||||
// https://matrix.org/docs/spec/client_server/latest#calculating-the-display-name-for-a-room.
|
||||
// the order in which we check for a name ^^
|
||||
if let Some(name) = &self.name {
|
||||
|
@ -126,19 +134,21 @@ impl RoomName {
|
|||
} else if !self.aliases.is_empty() {
|
||||
self.aliases[0].alias().to_string()
|
||||
} else {
|
||||
let mut names = members
|
||||
.values()
|
||||
.flat_map(|m| m.display_name.clone())
|
||||
.take(3)
|
||||
.collect::<Vec<_>>();
|
||||
let joined = self.joined_member_count.unwrap_or(UInt::max_value());
|
||||
let invited = self.invited_member_count.unwrap_or(UInt::max_value());
|
||||
let heroes = UInt::new(self.heroes.len() as u64).unwrap();
|
||||
let one = UInt::new(1).unwrap();
|
||||
|
||||
if names.is_empty() {
|
||||
// TODO implement the rest of display name for room spec
|
||||
format!("Room {}", room_id)
|
||||
} else {
|
||||
// stabilize order
|
||||
if heroes >= (joined + invited - one) {
|
||||
let mut names = self.heroes.iter().take(3).cloned().collect::<Vec<String>>();
|
||||
names.sort();
|
||||
names.join(", ")
|
||||
} else if heroes < (joined + invited - one) && invited + joined > one {
|
||||
let mut names = self.heroes.iter().take(3).cloned().collect::<Vec<String>>();
|
||||
names.sort();
|
||||
format!("{}, and {} others", names.join(", "), (joined + invited))
|
||||
} else {
|
||||
format!("Empty Room (was {} others)", members.len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +179,7 @@ impl Room {
|
|||
|
||||
/// Return the display name of the room.
|
||||
pub fn calculate_name(&self) -> String {
|
||||
self.room_name.calculate_name(&self.room_id, &self.members)
|
||||
self.room_name.calculate_name(&self.members)
|
||||
}
|
||||
|
||||
/// Is the room a encrypted room.
|
||||
|
@ -239,6 +249,17 @@ impl Room {
|
|||
true
|
||||
}
|
||||
|
||||
pub(crate) fn set_room_summary(&mut self, summary: &RoomSummary) {
|
||||
let RoomSummary {
|
||||
heroes,
|
||||
joined_member_count,
|
||||
invited_member_count,
|
||||
} = summary;
|
||||
self.room_name.heroes = heroes.clone();
|
||||
self.room_name.invited_member_count = invited_member_count.clone();
|
||||
self.room_name.joined_member_count = joined_member_count.clone();
|
||||
}
|
||||
|
||||
/// Handle a room.member updating the room state if necessary.
|
||||
///
|
||||
/// Returns true if the joined member list changed, false otherwise.
|
||||
|
|
Loading…
Reference in a new issue