session: Port to glib::Properties macro
This commit is contained in:
parent
46d585b185
commit
7869be72c1
|
@ -100,7 +100,7 @@ mod imp {
|
|||
|
||||
if let Some(session) = session {
|
||||
if let Some(session) = session.downcast_ref::<Session>() {
|
||||
let user = session.user().unwrap();
|
||||
let user = session.user();
|
||||
|
||||
let avatar_data_handler = user
|
||||
.bind_property("avatar-data", &*self.avatar, "data")
|
||||
|
|
|
@ -262,7 +262,7 @@ impl AuthDialog {
|
|||
stack.set_visible_child_name(AuthType::Password.as_ref());
|
||||
self.show_and_wait_for_response().await?;
|
||||
|
||||
let user_id = session.user().unwrap().user_id().to_string();
|
||||
let user_id = session.user_id().to_string();
|
||||
let password = self.imp().password.text().to_string();
|
||||
|
||||
let data = assign!(
|
||||
|
|
|
@ -162,7 +162,8 @@ impl UserFacingError for oo7::dbus::Error {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, glib::Boxed)]
|
||||
#[boxed_type(name = "StoredSession")]
|
||||
pub struct StoredSession {
|
||||
pub homeserver: Url,
|
||||
pub user_id: OwnedUserId,
|
||||
|
|
|
@ -288,8 +288,7 @@ impl Event {
|
|||
fn set_room(&self, room: Room) {
|
||||
let imp = self.imp();
|
||||
imp.room.set(Some(&room));
|
||||
imp.reactions
|
||||
.set_user(room.session().user().unwrap().clone());
|
||||
imp.reactions.set_user(room.session().user());
|
||||
}
|
||||
|
||||
/// The underlying SDK timeline item of this `Event`.
|
||||
|
|
|
@ -219,10 +219,8 @@ impl Member {
|
|||
self.set_membership((&event.content().membership).into());
|
||||
|
||||
let session = self.session();
|
||||
if let Some(user) = session.user() {
|
||||
if user.user_id() == self.user_id() {
|
||||
session.update_user_profile();
|
||||
}
|
||||
if session.user_id() == self.user_id() {
|
||||
session.update_user_profile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -746,11 +746,12 @@ impl Room {
|
|||
}
|
||||
|
||||
fn handle_receipt_event(&self, content: ReceiptEventContent) {
|
||||
let own_user_id = self.session().user().unwrap().user_id();
|
||||
let session = self.session();
|
||||
let own_user_id = session.user_id();
|
||||
|
||||
for (_event_id, receipts) in content.iter() {
|
||||
if let Some(users) = receipts.get(&ReceiptType::Read) {
|
||||
if users.contains_key(&own_user_id) {
|
||||
if users.contains_key(own_user_id) {
|
||||
self.update_is_read();
|
||||
}
|
||||
}
|
||||
|
@ -767,7 +768,8 @@ impl Room {
|
|||
return;
|
||||
};
|
||||
|
||||
let own_user_id = self.session().user().unwrap().user_id();
|
||||
let session = self.session();
|
||||
let own_user_id = session.user_id();
|
||||
|
||||
let members = content
|
||||
.user_ids
|
||||
|
@ -982,10 +984,7 @@ impl Room {
|
|||
return;
|
||||
}
|
||||
|
||||
let Some(own_user_id) = self.session().user().map(|user| user.user_id()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let own_user_id = self.session().user_id().to_owned();
|
||||
let matrix_room_clone = matrix_room.clone();
|
||||
let handle =
|
||||
spawn_tokio!(async move { matrix_room_clone.get_member_no_sync(&own_user_id).await });
|
||||
|
@ -1211,7 +1210,7 @@ impl Room {
|
|||
room_action: PowerLevelAction,
|
||||
) -> gtk::ClosureExpression {
|
||||
let session = self.session();
|
||||
let user_id = session.user().unwrap().user_id();
|
||||
let user_id = session.user_id().to_owned();
|
||||
self.power_levels()
|
||||
.member_is_allowed_to_expr(user_id, room_action)
|
||||
}
|
||||
|
@ -1626,7 +1625,8 @@ impl Room {
|
|||
}
|
||||
};
|
||||
|
||||
let own_user_id = self.session().user().unwrap().user_id();
|
||||
let session = self.session();
|
||||
let own_user_id = session.user_id();
|
||||
let mut has_own_member = false;
|
||||
let mut other_member = None;
|
||||
|
||||
|
|
|
@ -715,7 +715,7 @@ impl Timeline {
|
|||
/// Returns `None` if it is not possible to know, for example if there are
|
||||
/// no events in the Timeline.
|
||||
pub async fn has_unread_messages(&self) -> Option<bool> {
|
||||
let own_user_id = self.room().session().user().unwrap().user_id();
|
||||
let own_user_id = self.room().session().user_id().to_owned();
|
||||
let matrix_timeline = self.matrix_timeline();
|
||||
|
||||
let user_receipt_item = spawn_tokio!(async move {
|
||||
|
|
|
@ -35,7 +35,7 @@ use super::{
|
|||
use crate::{
|
||||
prelude::*,
|
||||
secret::StoredSession,
|
||||
session_list::{BoxedStoredSession, SessionInfo, SessionInfoImpl},
|
||||
session_list::{SessionInfo, SessionInfoImpl},
|
||||
spawn, spawn_tokio,
|
||||
utils::{
|
||||
check_if_reachable,
|
||||
|
@ -57,23 +57,39 @@ pub enum SessionState {
|
|||
Ready = 2,
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use std::cell::{Cell, RefCell};
|
||||
#[derive(Clone, Debug, glib::Boxed)]
|
||||
#[boxed_type(name = "BoxedClient")]
|
||||
pub struct BoxedClient(Client);
|
||||
|
||||
use once_cell::{sync::Lazy, unsync::OnceCell};
|
||||
mod imp {
|
||||
use std::cell::{Cell, OnceCell, RefCell};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, glib::Properties)]
|
||||
#[properties(wrapper_type = super::Session)]
|
||||
pub struct Session {
|
||||
pub client: TokioDrop<Client>,
|
||||
/// The Matrix client.
|
||||
#[property(construct_only)]
|
||||
pub client: TokioDrop<BoxedClient>,
|
||||
/// The list model of the sidebar.
|
||||
#[property(get = Self::sidebar_list_model)]
|
||||
pub sidebar_list_model: OnceCell<SidebarListModel>,
|
||||
/// The user of this session.
|
||||
#[property(get = Self::user)]
|
||||
pub user: OnceCell<User>,
|
||||
/// The current state of the session.
|
||||
#[property(get, builder(SessionState::default()))]
|
||||
pub state: Cell<SessionState>,
|
||||
pub sync_tokio_handle: RefCell<Option<JoinHandle<()>>>,
|
||||
pub offline_handler_id: RefCell<Option<SignalHandlerId>>,
|
||||
/// Whether this session has a connection to the homeserver.
|
||||
#[property(get)]
|
||||
pub offline: Cell<bool>,
|
||||
/// The current settings for this session.
|
||||
#[property(get, construct_only)]
|
||||
pub settings: OnceCell<SessionSettings>,
|
||||
/// The notifications API for this session.
|
||||
pub notifications: Notifications,
|
||||
}
|
||||
|
||||
|
@ -84,51 +100,8 @@ mod imp {
|
|||
type ParentType = SessionInfo;
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for Session {
|
||||
fn properties() -> &'static [glib::ParamSpec] {
|
||||
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
|
||||
vec![
|
||||
glib::ParamSpecObject::builder::<SidebarListModel>("sidebar-list-model")
|
||||
.read_only()
|
||||
.build(),
|
||||
glib::ParamSpecObject::builder::<User>("user")
|
||||
.read_only()
|
||||
.build(),
|
||||
glib::ParamSpecBoolean::builder("offline")
|
||||
.read_only()
|
||||
.build(),
|
||||
glib::ParamSpecEnum::builder::<SessionState>("state")
|
||||
.read_only()
|
||||
.build(),
|
||||
glib::ParamSpecObject::builder::<SessionSettings>("settings")
|
||||
.construct_only()
|
||||
.build(),
|
||||
]
|
||||
});
|
||||
|
||||
PROPERTIES.as_ref()
|
||||
}
|
||||
|
||||
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||
match pspec.name() {
|
||||
"settings" => self.settings.set(value.get().unwrap()).unwrap(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||
let obj = self.obj();
|
||||
|
||||
match pspec.name() {
|
||||
"sidebar-list-model" => obj.sidebar_list_model().to_value(),
|
||||
"user" => obj.user().to_value(),
|
||||
"offline" => obj.is_offline().to_value(),
|
||||
"state" => obj.state().to_value(),
|
||||
"settings" => obj.settings().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
let obj = self.obj();
|
||||
|
@ -159,7 +132,29 @@ mod imp {
|
|||
|
||||
impl SessionInfoImpl for Session {
|
||||
fn avatar_data(&self) -> AvatarData {
|
||||
self.obj().user().unwrap().avatar_data().clone()
|
||||
self.obj().user().avatar_data().clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Session {
|
||||
/// The list model of the sidebar.
|
||||
fn sidebar_list_model(&self) -> SidebarListModel {
|
||||
let obj = self.obj();
|
||||
self.sidebar_list_model
|
||||
.get_or_init(|| {
|
||||
let item_list =
|
||||
ItemList::new(&RoomList::new(&obj), &VerificationList::new(&obj));
|
||||
SidebarListModel::new(&item_list)
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
/// The user of the session.
|
||||
fn user(&self) -> User {
|
||||
let obj = self.obj();
|
||||
self.user
|
||||
.get_or_init(|| User::new(&obj, &obj.info().user_id))
|
||||
.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,29 +182,19 @@ impl Session {
|
|||
stored_session: StoredSession,
|
||||
settings: SessionSettings,
|
||||
) -> Result<Self, ClientSetupError> {
|
||||
let obj = glib::Object::builder::<Self>()
|
||||
.property("info", BoxedStoredSession(stored_session.clone()))
|
||||
.property("settings", settings)
|
||||
.build();
|
||||
|
||||
let stored_session_clone = stored_session.clone();
|
||||
let client =
|
||||
spawn_tokio!(async move { matrix::client_with_stored_session(stored_session).await })
|
||||
.await
|
||||
.unwrap()?;
|
||||
spawn_tokio!(
|
||||
async move { matrix::client_with_stored_session(stored_session_clone).await }
|
||||
)
|
||||
.await
|
||||
.unwrap()?;
|
||||
|
||||
let imp = obj.imp();
|
||||
imp.client.set(client).unwrap();
|
||||
|
||||
let user = User::new(&obj, &obj.info().user_id);
|
||||
imp.user.set(user).unwrap();
|
||||
obj.notify("user");
|
||||
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
/// The current state of the session.
|
||||
pub fn state(&self) -> SessionState {
|
||||
self.imp().state.get()
|
||||
Ok(glib::Object::builder()
|
||||
.property("info", &stored_session)
|
||||
.property("settings", settings)
|
||||
.property("client", &BoxedClient(client))
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Set the current state of the session.
|
||||
|
@ -223,9 +208,10 @@ impl Session {
|
|||
}
|
||||
|
||||
self.imp().state.set(state);
|
||||
self.notify("state");
|
||||
self.notify_state();
|
||||
}
|
||||
|
||||
/// Finish initialization of this session.
|
||||
pub async fn prepare(&self) {
|
||||
self.update_user_profile();
|
||||
self.update_offline().await;
|
||||
|
@ -240,8 +226,9 @@ impl Session {
|
|||
debug!("A new session was prepared");
|
||||
}
|
||||
|
||||
/// Start syncing the Matrix client.
|
||||
fn sync(&self) {
|
||||
if self.state() < SessionState::InitialSync || self.is_offline() {
|
||||
if self.state() < SessionState::InitialSync || self.offline() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -326,38 +313,22 @@ impl Session {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
/// The current settings for this session.
|
||||
pub fn settings(&self) -> &SessionSettings {
|
||||
self.imp().settings.get().unwrap()
|
||||
}
|
||||
|
||||
/// The room list of this session.
|
||||
pub fn room_list(&self) -> RoomList {
|
||||
self.sidebar_list_model().item_list().room_list()
|
||||
}
|
||||
|
||||
/// The verification list of this session.
|
||||
pub fn verification_list(&self) -> VerificationList {
|
||||
self.sidebar_list_model().item_list().verification_list()
|
||||
}
|
||||
|
||||
/// The list model of the sidebar.
|
||||
pub fn sidebar_list_model(&self) -> &SidebarListModel {
|
||||
self.imp().sidebar_list_model.get_or_init(|| {
|
||||
let item_list = ItemList::new(&RoomList::new(self), &VerificationList::new(self));
|
||||
SidebarListModel::new(&item_list)
|
||||
})
|
||||
}
|
||||
|
||||
/// The user of this session.
|
||||
pub fn user(&self) -> Option<&User> {
|
||||
self.imp().user.get()
|
||||
}
|
||||
|
||||
/// Update the profile of this session’s user.
|
||||
///
|
||||
/// Fetches the updated profile and updates the local data.
|
||||
pub fn update_user_profile(&self) {
|
||||
let client = self.client();
|
||||
let user = self.user().unwrap().to_owned();
|
||||
let user = self.user();
|
||||
|
||||
let handle = spawn_tokio!(async move { client.account().get_profile().await });
|
||||
|
||||
|
@ -372,40 +343,38 @@ impl Session {
|
|||
});
|
||||
}
|
||||
|
||||
/// The Matrix client.
|
||||
pub fn client(&self) -> Client {
|
||||
self.imp()
|
||||
.client
|
||||
.get()
|
||||
.expect("The session wasn't prepared")
|
||||
.0
|
||||
.clone()
|
||||
}
|
||||
|
||||
/// Whether this session has a connection to the homeserver.
|
||||
pub fn is_offline(&self) -> bool {
|
||||
self.imp().offline.get()
|
||||
}
|
||||
|
||||
/// Update whether this session is offline.
|
||||
async fn update_offline(&self) {
|
||||
let imp = self.imp();
|
||||
let monitor = gio::NetworkMonitor::default();
|
||||
|
||||
let is_offline = if monitor.is_network_available() {
|
||||
let offline = if monitor.is_network_available() {
|
||||
!check_if_reachable(&self.homeserver()).await
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
if self.is_offline() == is_offline {
|
||||
if self.offline() == offline {
|
||||
return;
|
||||
}
|
||||
|
||||
if is_offline {
|
||||
if offline {
|
||||
debug!("This session is now offline");
|
||||
} else {
|
||||
debug!("This session is now online");
|
||||
}
|
||||
|
||||
imp.offline.set(is_offline);
|
||||
imp.offline.set(offline);
|
||||
|
||||
if let Some(handle) = imp.sync_tokio_handle.take() {
|
||||
handle.abort();
|
||||
|
@ -414,25 +383,28 @@ impl Session {
|
|||
// Restart the sync loop when online
|
||||
self.sync();
|
||||
|
||||
self.notify("offline");
|
||||
self.notify_offline();
|
||||
}
|
||||
|
||||
/// Connect to the signal emitted when this session is logged out.
|
||||
pub fn connect_logged_out<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.connect_notify_local(Some("state"), move |obj, _| {
|
||||
self.connect_state_notify(move |obj| {
|
||||
if obj.state() == SessionState::LoggedOut {
|
||||
f(obj);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Connect to the signal emitted when this session is ready.
|
||||
pub fn connect_ready<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
|
||||
self.connect_notify_local(Some("state"), move |obj, _| {
|
||||
self.connect_state_notify(move |obj| {
|
||||
if obj.state() == SessionState::Ready {
|
||||
f(obj);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Handle the response received via sync.
|
||||
fn handle_sync_response(&self, response: Result<SyncResponse, matrix_sdk::Error>) {
|
||||
debug!("Received sync response");
|
||||
match response {
|
||||
|
@ -456,6 +428,7 @@ impl Session {
|
|||
}
|
||||
}
|
||||
|
||||
/// Log out of this session.
|
||||
pub async fn logout(&self) -> Result<(), String> {
|
||||
debug!("The session is about to be logged out");
|
||||
|
||||
|
@ -494,6 +467,7 @@ impl Session {
|
|||
);
|
||||
}
|
||||
|
||||
/// Clean up this session after it was logged out.
|
||||
async fn cleanup_session(&self) {
|
||||
let imp = self.imp();
|
||||
|
||||
|
@ -514,6 +488,7 @@ impl Session {
|
|||
debug!("The logged out session was cleaned up");
|
||||
}
|
||||
|
||||
/// Listen to changes to the list of direct rooms.
|
||||
fn setup_direct_room_handler(&self) {
|
||||
let session_weak = glib::SendWeakRef::from(self.downgrade());
|
||||
self.client().add_event_handler(
|
||||
|
@ -556,6 +531,7 @@ impl Session {
|
|||
);
|
||||
}
|
||||
|
||||
/// The notifications API of this session.
|
||||
pub fn notifications(&self) -> &Notifications {
|
||||
&self.imp().notifications
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use tracing::error;
|
|||
|
||||
use crate::{
|
||||
components::Pill,
|
||||
prelude::*,
|
||||
session::model::{
|
||||
AvatarData, AvatarImage, AvatarUriSource, IdentityVerification, Session, VerificationState,
|
||||
},
|
||||
|
@ -157,7 +158,7 @@ impl User {
|
|||
}
|
||||
|
||||
pub async fn verify_identity(&self) -> IdentityVerification {
|
||||
let request = IdentityVerification::create(self.session(), Some(self)).await;
|
||||
let request = IdentityVerification::create(self.session(), Some(self.clone())).await;
|
||||
self.session().verification_list().add(request.clone());
|
||||
// FIXME: actually listen to room events to get updates for verification state
|
||||
request.connect_notify_local(
|
||||
|
@ -240,9 +241,7 @@ pub trait UserExt: IsA<User> {
|
|||
fn allowed_actions(&self) -> UserActions {
|
||||
let user = self.upcast_ref();
|
||||
|
||||
let is_other = self.session().user().map_or(false, |session_user| {
|
||||
session_user.user_id() != self.user_id()
|
||||
});
|
||||
let is_other = self.session().user_id() != self.user_id();
|
||||
|
||||
if !user.is_verified() && is_other {
|
||||
UserActions::VERIFY
|
||||
|
|
|
@ -278,7 +278,7 @@ mod imp {
|
|||
|
||||
// We don't need to track ourselves because we show "Login Request" as name in
|
||||
// that case.
|
||||
if obj.user() != obj.session().user().unwrap() {
|
||||
if obj.user() != &obj.session().user() {
|
||||
obj.user().connect_notify_local(
|
||||
Some("display-name"),
|
||||
clone!(@weak obj => move |_, _| {
|
||||
|
@ -337,11 +337,11 @@ impl IdentityVerification {
|
|||
///
|
||||
/// If `User` is `None` a new session verification is started for our own
|
||||
/// user and send to other devices.
|
||||
pub async fn create(session: &Session, user: Option<&User>) -> Self {
|
||||
pub async fn create(session: &Session, user: Option<User>) -> Self {
|
||||
let user = if let Some(user) = user {
|
||||
user
|
||||
} else {
|
||||
session.user().unwrap()
|
||||
session.user()
|
||||
};
|
||||
|
||||
let has_camera =
|
||||
|
@ -364,7 +364,7 @@ impl IdentityVerification {
|
|||
.property("supported-methods", supported_methods)
|
||||
.property("flow-id", request.flow_id())
|
||||
.property("session", session)
|
||||
.property("user", user)
|
||||
.property("user", &user)
|
||||
.property("start-time", &glib::DateTime::now_local().unwrap())
|
||||
.build();
|
||||
|
||||
|
@ -378,7 +378,7 @@ impl IdentityVerification {
|
|||
error!("Starting a verification failed: Crypto identity wasn't found");
|
||||
}
|
||||
|
||||
Self::for_error(session, user, &glib::DateTime::now_local().unwrap())
|
||||
Self::for_error(session, &user, &glib::DateTime::now_local().unwrap())
|
||||
}
|
||||
|
||||
fn start_handler(&self) {
|
||||
|
@ -595,7 +595,7 @@ impl IdentityVerification {
|
|||
/// The mode of this verification.
|
||||
pub fn mode(&self) -> Mode {
|
||||
let session = self.session();
|
||||
let our_user = session.user().unwrap();
|
||||
let our_user = session.user();
|
||||
if our_user.user_id() == self.user().user_id() {
|
||||
if self.force_current_session() {
|
||||
Mode::CurrentSession
|
||||
|
@ -622,7 +622,7 @@ impl IdentityVerification {
|
|||
|
||||
/// The display name of this verification request.
|
||||
pub fn display_name(&self) -> String {
|
||||
if self.user() != self.session().user().unwrap() {
|
||||
if self.user() != &self.session().user() {
|
||||
self.user().display_name()
|
||||
} else {
|
||||
// TODO: give this request a name based on the device
|
||||
|
|
|
@ -140,7 +140,7 @@ impl VerificationList {
|
|||
Some(request)
|
||||
} else {
|
||||
let session = self.session();
|
||||
let user = session.user().unwrap();
|
||||
let user = session.user();
|
||||
// ToDevice verifications can only be send by us
|
||||
if *e.sender != *user.user_id() {
|
||||
warn!("Received a device verification event from a different user, which isn't allowed");
|
||||
|
@ -158,7 +158,7 @@ impl VerificationList {
|
|||
let request = IdentityVerification::for_flow_id(
|
||||
e.content.transaction_id.as_str(),
|
||||
&session,
|
||||
user,
|
||||
&user,
|
||||
&start_time,
|
||||
);
|
||||
self.add(request.clone());
|
||||
|
@ -228,7 +228,7 @@ impl VerificationList {
|
|||
};
|
||||
|
||||
let session = self.session();
|
||||
let own_user_id = session.user().unwrap().user_id();
|
||||
let own_user_id = session.user_id();
|
||||
|
||||
let user_id_to_verify = if request.to == own_user_id {
|
||||
// The request was sent by another user to verify us
|
||||
|
@ -407,7 +407,7 @@ impl VerificationList {
|
|||
pub fn get_session(&self) -> Option<IdentityVerification> {
|
||||
let list = self.imp().list.borrow();
|
||||
let session = self.session();
|
||||
let user_id = session.user().unwrap().user_id();
|
||||
let user_id = session.user_id();
|
||||
|
||||
for (_, item) in list.iter() {
|
||||
if !item.is_finished() && item.user().user_id() == user_id {
|
||||
|
|
|
@ -128,10 +128,8 @@ impl DeactivateAccountSubpage {
|
|||
fn user_id(&self) -> String {
|
||||
self.session()
|
||||
.as_ref()
|
||||
.and_then(|session| session.user())
|
||||
.map(|session| session.user_id().to_string())
|
||||
.unwrap()
|
||||
.user_id()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn update_button(&self) {
|
||||
|
|
|
@ -198,9 +198,8 @@ impl GeneralPage {
|
|||
fn user(&self) -> User {
|
||||
self.session()
|
||||
.as_ref()
|
||||
.and_then(|session| session.user())
|
||||
.map(|session| session.user())
|
||||
.unwrap()
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
fn init_avatar(&self) {
|
||||
|
|
|
@ -180,8 +180,8 @@ impl NotificationsPage {
|
|||
},
|
||||
Ok(None) => {
|
||||
warn!("Could not find push rules, using the default ruleset instead.");
|
||||
let user_id = session.user().unwrap().user_id();
|
||||
self.update_page(Ruleset::server_default(&user_id));
|
||||
let user_id = session.user_id();
|
||||
self.update_page(Ruleset::server_default(user_id));
|
||||
}
|
||||
Err(error) => {
|
||||
error!("Could not get push rules: {error}");
|
||||
|
|
|
@ -88,7 +88,7 @@ impl ServerList {
|
|||
|
||||
imp.session.set(Some(&session));
|
||||
|
||||
let user_id = session.user().unwrap().user_id();
|
||||
let user_id = session.user_id();
|
||||
imp.list.replace(vec![Server::with_default_server(
|
||||
user_id.server_name().as_str(),
|
||||
)]);
|
||||
|
|
|
@ -477,12 +477,8 @@ impl ItemRow {
|
|||
]);
|
||||
|
||||
if let TimelineItemContent::Message(message) = event.content() {
|
||||
let own_user_id = event
|
||||
.room()
|
||||
.session()
|
||||
.user()
|
||||
.map(|user| user.user_id())
|
||||
.unwrap();
|
||||
let session = event.room().session();
|
||||
let own_user_id = session.user_id();
|
||||
let is_from_own_user = event.sender_id() == own_user_id;
|
||||
|
||||
// Remove message
|
||||
|
|
|
@ -880,8 +880,7 @@ impl MessageToolbar {
|
|||
fn update_completion(&self, room: Option<&Room>) {
|
||||
let completion = &self.imp().completion;
|
||||
|
||||
completion
|
||||
.set_user_id(room.and_then(|r| r.session().user().map(|u| u.user_id().to_string())));
|
||||
completion.set_user_id(room.map(|r| r.session().user_id().to_string()));
|
||||
// `RoomHistory` should have a strong reference to the list so we can use
|
||||
// `get_or_create_members()`.
|
||||
completion.set_members(room.map(|r| r.get_or_create_members()));
|
||||
|
@ -928,31 +927,30 @@ impl MessageToolbar {
|
|||
|
||||
fn set_up_can_send_messages(&self, room: Option<&Room>) {
|
||||
if let Some(room) = room {
|
||||
if let Some(own_user_id) = room.session().user().map(|u| u.user_id().to_owned()) {
|
||||
let imp = self.imp();
|
||||
let own_user_id = room.session().user_id().to_owned();
|
||||
let imp = self.imp();
|
||||
|
||||
let own_member = room
|
||||
.get_or_create_members()
|
||||
.get_or_create(own_user_id.clone());
|
||||
let own_member = room
|
||||
.get_or_create_members()
|
||||
.get_or_create(own_user_id.clone());
|
||||
|
||||
// We don't need to keep the handler around, the member should be dropped when
|
||||
// switching rooms.
|
||||
own_member.connect_notify_local(
|
||||
Some("membership"),
|
||||
clone!(@weak self as obj => move |_, _| {
|
||||
obj.update_can_send_messages();
|
||||
}),
|
||||
);
|
||||
imp.own_member.set(Some(&own_member));
|
||||
// We don't need to keep the handler around, the member should be dropped when
|
||||
// switching rooms.
|
||||
own_member.connect_notify_local(
|
||||
Some("membership"),
|
||||
clone!(@weak self as obj => move |_, _| {
|
||||
obj.update_can_send_messages();
|
||||
}),
|
||||
);
|
||||
imp.own_member.set(Some(&own_member));
|
||||
|
||||
let power_levels_handler = room.power_levels().connect_notify_local(
|
||||
Some("power-levels"),
|
||||
clone!(@weak self as obj => move |_, _| {
|
||||
obj.update_can_send_messages();
|
||||
}),
|
||||
);
|
||||
imp.power_levels_handler.replace(Some(power_levels_handler));
|
||||
}
|
||||
let power_levels_handler = room.power_levels().connect_notify_local(
|
||||
Some("power-levels"),
|
||||
clone!(@weak self as obj => move |_, _| {
|
||||
obj.update_can_send_messages();
|
||||
}),
|
||||
);
|
||||
imp.power_levels_handler.replace(Some(power_levels_handler));
|
||||
}
|
||||
|
||||
self.update_can_send_messages();
|
||||
|
|
|
@ -220,7 +220,7 @@ impl DmUserList {
|
|||
}
|
||||
|
||||
self.load_dm_rooms().await;
|
||||
let own_user_id = session.user().unwrap().user_id();
|
||||
let own_user_id = session.user_id();
|
||||
let dm_rooms = self.imp().dm_rooms.borrow().clone();
|
||||
|
||||
let mut users: Vec<DmUser> = vec![];
|
||||
|
|
|
@ -139,9 +139,9 @@ impl RoomCreation {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some(user) = session.as_ref().and_then(|session| session.user()) {
|
||||
if let Some(session) = session {
|
||||
imp.server_name
|
||||
.set_label(&format!(":{}", user.user_id().server_name()));
|
||||
.set_label(&format!(":{}", session.user_id().server_name()));
|
||||
}
|
||||
|
||||
imp.session.set(session);
|
||||
|
|
|
@ -278,10 +278,10 @@ impl Sidebar {
|
|||
let handler_id = session.connect_notify_local(
|
||||
Some("offline"),
|
||||
clone!(@weak self as obj => move |session, _| {
|
||||
obj.imp().offline_banner.set_revealed(session.is_offline());
|
||||
obj.imp().offline_banner.set_revealed(session.offline());
|
||||
}),
|
||||
);
|
||||
self.imp().offline_banner.set_revealed(session.is_offline());
|
||||
self.imp().offline_banner.set_revealed(session.offline());
|
||||
|
||||
self.imp().offline_handler_id.replace(Some(handler_id));
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::{ops::Deref, sync::Arc};
|
|||
|
||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||
|
||||
use super::{BoxedStoredSession, SessionInfo, SessionInfoImpl};
|
||||
use super::{SessionInfo, SessionInfoImpl};
|
||||
use crate::{
|
||||
prelude::*, secret::StoredSession, session::model::AvatarData, utils::matrix::ClientSetupError,
|
||||
};
|
||||
|
@ -67,7 +67,7 @@ impl FailedSession {
|
|||
/// Constructs a new `FailedSession` with the given info and error.
|
||||
pub fn new(stored_session: StoredSession, error: ClientSetupError) -> Self {
|
||||
glib::Object::builder()
|
||||
.property("info", BoxedStoredSession(stored_session))
|
||||
.property("info", &stored_session)
|
||||
.property("error", BoxedClientSetupError(Arc::new(error)))
|
||||
.build()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use gtk::{glib, subclass::prelude::*};
|
||||
|
||||
use super::{BoxedStoredSession, SessionInfo, SessionInfoImpl};
|
||||
use super::{SessionInfo, SessionInfoImpl};
|
||||
use crate::{prelude::*, secret::StoredSession, session::model::AvatarData};
|
||||
|
||||
mod imp {
|
||||
|
@ -48,7 +48,7 @@ impl NewSession {
|
|||
/// Constructs a new `NewSession` with the given info.
|
||||
pub fn new(stored_session: StoredSession) -> Self {
|
||||
glib::Object::builder()
|
||||
.property("info", BoxedStoredSession(stored_session))
|
||||
.property("info", &stored_session)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use gtk::{glib, prelude::*, subclass::prelude::*};
|
||||
use ruma::{DeviceId, UserId};
|
||||
use url::Url;
|
||||
|
||||
use crate::{secret::StoredSession, session::model::AvatarData};
|
||||
|
||||
#[derive(Clone, Debug, glib::Boxed)]
|
||||
#[boxed_type(name = "BoxedStoredSession")]
|
||||
pub struct BoxedStoredSession(pub StoredSession);
|
||||
|
||||
impl Deref for BoxedStoredSession {
|
||||
type Target = StoredSession;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use std::{cell::OnceCell, marker::PhantomData};
|
||||
|
||||
|
@ -43,7 +29,7 @@ mod imp {
|
|||
pub struct SessionInfo {
|
||||
/// The Matrix session's info.
|
||||
#[property(get, construct_only)]
|
||||
pub info: OnceCell<BoxedStoredSession>,
|
||||
pub info: OnceCell<StoredSession>,
|
||||
/// The Matrix session's user ID.
|
||||
#[property(get = Self::user_id)]
|
||||
pub user_id: PhantomData<String>,
|
||||
|
@ -75,7 +61,7 @@ mod imp {
|
|||
impl SessionInfo {
|
||||
/// The Matrix session's info.
|
||||
pub fn info(&self) -> &StoredSession {
|
||||
&self.info.get().unwrap().0
|
||||
self.info.get().unwrap()
|
||||
}
|
||||
|
||||
/// The Matrix session's user ID.
|
||||
|
|
|
@ -417,6 +417,28 @@ impl<T> Drop for TokioDrop<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: glib::Property> glib::Property for TokioDrop<T> {
|
||||
type Value = T::Value;
|
||||
}
|
||||
|
||||
impl<T> glib::PropertyGet for TokioDrop<T> {
|
||||
type Value = T;
|
||||
|
||||
fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {
|
||||
f(self.get().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> glib::PropertySet for TokioDrop<T> {
|
||||
type SetValue = T;
|
||||
|
||||
fn set(&self, v: Self::SetValue) {
|
||||
if self.set(v).is_err() {
|
||||
panic!("TokioDrop value was already set");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The state of a resource that can be loaded.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, glib::Enum)]
|
||||
#[enum_type(name = "LoadingState")]
|
||||
|
|
Loading…
Reference in New Issue