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