cargo fmt/clippy, move power levels into Room
parent
e987a9006b
commit
c2b3210cc9
|
@ -25,10 +25,7 @@ impl EventEmitter for EventCallback {
|
||||||
let member = rooms.members.get(&sender).unwrap();
|
let member = rooms.members.get(&sender).unwrap();
|
||||||
println!(
|
println!(
|
||||||
"{}: {}",
|
"{}: {}",
|
||||||
member
|
member.display_name.as_ref().unwrap_or(&sender.to_string()),
|
||||||
.display_name
|
|
||||||
.as_ref()
|
|
||||||
.unwrap_or(&sender.to_string()),
|
|
||||||
msg_body
|
msg_body
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,6 @@ use tokio::sync::Mutex;
|
||||||
/// println!(
|
/// println!(
|
||||||
/// "{}: {}",
|
/// "{}: {}",
|
||||||
/// member
|
/// member
|
||||||
/// .user
|
|
||||||
/// .display_name
|
/// .display_name
|
||||||
/// .as_ref()
|
/// .as_ref()
|
||||||
/// .unwrap_or(&sender.to_string()),
|
/// .unwrap_or(&sender.to_string()),
|
||||||
|
|
|
@ -26,11 +26,12 @@ use crate::events::room::{
|
||||||
encryption::EncryptionEvent,
|
encryption::EncryptionEvent,
|
||||||
member::{MemberEvent, MembershipChange},
|
member::{MemberEvent, MembershipChange},
|
||||||
name::NameEvent,
|
name::NameEvent,
|
||||||
power_levels::PowerLevelsEvent,
|
power_levels::{NotificationPowerLevels, PowerLevelsEvent, PowerLevelsEventContent},
|
||||||
};
|
};
|
||||||
|
use crate::events::EventType;
|
||||||
use crate::identifiers::{RoomAliasId, RoomId, UserId};
|
use crate::identifiers::{RoomAliasId, RoomId, UserId};
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::{Int, UInt};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
/// `RoomName` allows the calculation of a text room name.
|
/// `RoomName` allows the calculation of a text room name.
|
||||||
|
@ -43,6 +44,32 @@ pub struct RoomName {
|
||||||
aliases: Vec<RoomAliasId>,
|
aliases: Vec<RoomAliasId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct PowerLevels {
|
||||||
|
/// The level required to ban a user.
|
||||||
|
pub ban: Int,
|
||||||
|
/// The level required to send specific event types.
|
||||||
|
///
|
||||||
|
/// This is a mapping from event type to power level required.
|
||||||
|
pub events: HashMap<EventType, Int>,
|
||||||
|
/// The default level required to send message events.
|
||||||
|
pub events_default: Int,
|
||||||
|
/// The level required to invite a user.
|
||||||
|
pub invite: Int,
|
||||||
|
/// The level required to kick a user.
|
||||||
|
pub kick: Int,
|
||||||
|
/// The level required to redact an event.
|
||||||
|
pub redact: Int,
|
||||||
|
/// The default level required to send state events.
|
||||||
|
pub state_default: Int,
|
||||||
|
/// The default power level for every user in the room.
|
||||||
|
pub users_default: Int,
|
||||||
|
/// The power level requirements for specific notification types.
|
||||||
|
///
|
||||||
|
/// This is a mapping from `key` to power level for that notifications key.
|
||||||
|
pub notifications: Int,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// A Matrix rooom.
|
/// A Matrix rooom.
|
||||||
pub struct Room {
|
pub struct Room {
|
||||||
|
@ -58,6 +85,8 @@ pub struct Room {
|
||||||
pub members: HashMap<UserId, RoomMember>,
|
pub members: HashMap<UserId, RoomMember>,
|
||||||
/// A list of users that are currently typing.
|
/// A list of users that are currently typing.
|
||||||
pub typing_users: Vec<UserId>,
|
pub typing_users: Vec<UserId>,
|
||||||
|
/// The power level requirements for specific actions in this room
|
||||||
|
pub power_levels: Option<PowerLevels>,
|
||||||
// TODO when encryption events are handled we store algorithm used and rotation time.
|
// TODO when encryption events are handled we store algorithm used and rotation time.
|
||||||
/// A flag indicating if the room is encrypted.
|
/// A flag indicating if the room is encrypted.
|
||||||
pub encrypted: bool,
|
pub encrypted: bool,
|
||||||
|
@ -131,6 +160,7 @@ impl Room {
|
||||||
creator: None,
|
creator: None,
|
||||||
members: HashMap::new(),
|
members: HashMap::new(),
|
||||||
typing_users: Vec::new(),
|
typing_users: Vec::new(),
|
||||||
|
power_levels: None,
|
||||||
encrypted: false,
|
encrypted: false,
|
||||||
unread_highlight: None,
|
unread_highlight: None,
|
||||||
unread_notifications: None,
|
unread_notifications: None,
|
||||||
|
@ -156,7 +186,7 @@ impl Room {
|
||||||
}
|
}
|
||||||
|
|
||||||
let member = RoomMember::new(event);
|
let member = RoomMember::new(event);
|
||||||
|
|
||||||
self.members
|
self.members
|
||||||
.insert(UserId::try_from(event.state_key.as_str()).unwrap(), member);
|
.insert(UserId::try_from(event.state_key.as_str()).unwrap(), member);
|
||||||
|
|
||||||
|
@ -180,6 +210,35 @@ impl Room {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_room_power_level(&mut self, event: &PowerLevelsEvent) -> bool {
|
||||||
|
let PowerLevelsEventContent {
|
||||||
|
ban,
|
||||||
|
events,
|
||||||
|
events_default,
|
||||||
|
invite,
|
||||||
|
kick,
|
||||||
|
redact,
|
||||||
|
state_default,
|
||||||
|
users_default,
|
||||||
|
notifications: NotificationPowerLevels { room },
|
||||||
|
..
|
||||||
|
} = &event.content;
|
||||||
|
|
||||||
|
let power = PowerLevels {
|
||||||
|
ban: *ban,
|
||||||
|
events: events.clone(),
|
||||||
|
events_default: *events_default,
|
||||||
|
invite: *invite,
|
||||||
|
kick: *kick,
|
||||||
|
redact: *redact,
|
||||||
|
state_default: *state_default,
|
||||||
|
users_default: *users_default,
|
||||||
|
notifications: *room,
|
||||||
|
};
|
||||||
|
self.power_levels = Some(power);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -192,10 +251,7 @@ impl Room {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if let Some(member) = self
|
if let Some(member) = self.members.get_mut(&user) {
|
||||||
.members
|
|
||||||
.get_mut(&user)
|
|
||||||
{
|
|
||||||
member.update_member(event)
|
member.update_member(event)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -239,22 +295,22 @@ impl Room {
|
||||||
///
|
///
|
||||||
/// Returns true if the room name changed, false otherwise.
|
/// Returns true if the room name changed, false otherwise.
|
||||||
pub fn handle_power_level(&mut self, event: &PowerLevelsEvent) -> bool {
|
pub fn handle_power_level(&mut self, event: &PowerLevelsEvent) -> bool {
|
||||||
// when getting a response from the actual matrix server `state_key`
|
// NOTE: this is always true, we assume that if we get an event their is an update.
|
||||||
// was empty, the spec says "state_key: A zero-length string."
|
let mut updated = self.set_room_power_level(event);
|
||||||
// for `m.room.power_levels` events
|
|
||||||
let user = if let Ok(id) = UserId::try_from(event.state_key.as_str()) {
|
let mut max_power = event.content.users_default;
|
||||||
id
|
for power in event.content.users.values() {
|
||||||
} else {
|
max_power = *power.max(&max_power);
|
||||||
return false;
|
|
||||||
};
|
|
||||||
if let Some(member) = self
|
|
||||||
.members
|
|
||||||
.get_mut(&user)
|
|
||||||
{
|
|
||||||
member.update_power(event)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for user in event.content.users.keys() {
|
||||||
|
if let Some(member) = self.members.get_mut(user) {
|
||||||
|
if member.update_power(event, max_power) {
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updated
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_encryption_event(&mut self, _event: &EncryptionEvent) -> bool {
|
fn handle_encryption_event(&mut self, _event: &EncryptionEvent) -> bool {
|
||||||
|
@ -297,6 +353,7 @@ impl Room {
|
||||||
StateEvent::RoomName(n) => self.handle_room_name(n),
|
StateEvent::RoomName(n) => self.handle_room_name(n),
|
||||||
StateEvent::RoomCanonicalAlias(ca) => self.handle_canonical(ca),
|
StateEvent::RoomCanonicalAlias(ca) => self.handle_canonical(ca),
|
||||||
StateEvent::RoomAliases(a) => self.handle_room_aliases(a),
|
StateEvent::RoomAliases(a) => self.handle_room_aliases(a),
|
||||||
|
StateEvent::RoomPowerLevels(p) => self.handle_power_level(p),
|
||||||
StateEvent::RoomEncryption(e) => self.handle_encryption_event(e),
|
StateEvent::RoomEncryption(e) => self.handle_encryption_event(e),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -337,6 +394,7 @@ mod test {
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -375,5 +433,7 @@ mod test {
|
||||||
for (_id, member) in &room.members {
|
for (_id, member) in &room.members {
|
||||||
assert_eq!(MembershipState::Join, member.membership);
|
assert_eq!(MembershipState::Join, member.membership);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert!(room.deref().power_levels.is_some())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use crate::events::collections::all::Event;
|
use crate::events::collections::all::Event;
|
||||||
|
use crate::events::presence::{PresenceEvent, PresenceEventContent, PresenceState};
|
||||||
use crate::events::room::{
|
use crate::events::room::{
|
||||||
member::{MemberEvent, MembershipChange, MembershipState},
|
member::{MemberEvent, MembershipChange, MembershipState},
|
||||||
power_levels::PowerLevelsEvent,
|
power_levels::PowerLevelsEvent,
|
||||||
};
|
};
|
||||||
use crate::events::presence::{PresenceEvent, PresenceEventContent, PresenceState};
|
|
||||||
use crate::identifiers::UserId;
|
use crate::identifiers::UserId;
|
||||||
|
|
||||||
use js_int::{Int, UInt};
|
use js_int::{Int, UInt};
|
||||||
|
@ -106,12 +106,7 @@ impl RoomMember {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_power(&mut self, event: &PowerLevelsEvent) -> bool {
|
pub fn update_power(&mut self, event: &PowerLevelsEvent, max_power: Int) -> bool {
|
||||||
let mut max_power = event.content.users_default;
|
|
||||||
for power in event.content.users.values() {
|
|
||||||
max_power = *power.max(&max_power);
|
|
||||||
}
|
|
||||||
|
|
||||||
let changed;
|
let changed;
|
||||||
if let Some(user_power) = event.content.users.get(&self.user_id) {
|
if let Some(user_power) = event.content.users.get(&self.user_id) {
|
||||||
changed = self.power_level != Some(*user_power);
|
changed = self.power_level != Some(*user_power);
|
||||||
|
@ -179,18 +174,16 @@ impl RoomMember {
|
||||||
|
|
||||||
self.presence_events.push(presence_ev.clone());
|
self.presence_events.push(presence_ev.clone());
|
||||||
self.avatar_url = avatar_url.clone();
|
self.avatar_url = avatar_url.clone();
|
||||||
self.currently_active = currently_active.clone();
|
self.currently_active = *currently_active;
|
||||||
self.display_name = displayname.clone();
|
self.display_name = displayname.clone();
|
||||||
self.last_active_ago = last_active_ago.clone();
|
self.last_active_ago = *last_active_ago;
|
||||||
self.presence = Some(presence.clone());
|
self.presence = Some(*presence);
|
||||||
self.status_msg = status_msg.clone();
|
self.status_msg = status_msg.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
use crate::identifiers::{EventId, RoomId, UserId};
|
use crate::identifiers::{EventId, RoomId, UserId};
|
||||||
use crate::{AsyncClient, Session, SyncSettings};
|
use crate::{AsyncClient, Session, SyncSettings};
|
||||||
|
|
||||||
|
@ -202,6 +195,7 @@ mod test {
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -240,11 +234,17 @@ mod test {
|
||||||
.lock()
|
.lock()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
for (_id, member) in &mut room.members {
|
let power = power_levels();
|
||||||
let power = power_levels();
|
assert!(room.handle_power_level(&power));
|
||||||
assert!(member.update_power(&power));
|
|
||||||
assert_eq!(MembershipState::Join, member.membership);
|
assert_eq!(
|
||||||
}
|
room.deref().power_levels.as_ref().unwrap().ban,
|
||||||
|
Int::new(40).unwrap()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
room.deref().power_levels.as_ref().unwrap().notifications,
|
||||||
|
Int::new(35).unwrap()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn power_levels() -> PowerLevelsEvent {
|
fn power_levels() -> PowerLevelsEvent {
|
||||||
|
|
Loading…
Reference in New Issue