Add update for device last_seen_ts. (closes #40)
Piggyback on presence ping for controlled device seen updates. Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -49,7 +49,7 @@ pub(crate) async fn set_displayname_route(
|
|||||||
// Presence update
|
// Presence update
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(set_display_name::v3::Response {})
|
Ok(set_display_name::v3::Response {})
|
||||||
@@ -149,7 +149,7 @@ pub(crate) async fn set_avatar_url_route(
|
|||||||
// Presence update
|
// Presence update
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,11 @@ pub(crate) async fn set_read_marker_route(
|
|||||||
|
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(sender_user, &ruma::presence::PresenceState::Online)
|
.maybe_ping_presence(
|
||||||
|
sender_user,
|
||||||
|
body.sender_device.as_deref(),
|
||||||
|
&ruma::presence::PresenceState::Online,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@@ -165,7 +169,11 @@ pub(crate) async fn create_receipt_route(
|
|||||||
|
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(sender_user, &ruma::presence::PresenceState::Online)
|
.maybe_ping_presence(
|
||||||
|
sender_user,
|
||||||
|
body.sender_device.as_deref(),
|
||||||
|
&ruma::presence::PresenceState::Online,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ pub(crate) async fn sync_events_route(
|
|||||||
|
|
||||||
let ping_presence = services
|
let ping_presence = services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(sender_user, &body.body.set_presence)
|
.maybe_ping_presence(sender_user, Some(sender_device), &body.body.set_presence)
|
||||||
.inspect_err(inspect_log)
|
.inspect_err(inspect_log)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ pub(crate) async fn sync_events_v5_route(
|
|||||||
let conn = conn_val.lock();
|
let conn = conn_val.lock();
|
||||||
let ping_presence = services
|
let ping_presence = services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(sender_user, &request.set_presence)
|
.maybe_ping_presence(sender_user, Some(sender_device), &request.set_presence)
|
||||||
.inspect_err(inspect_log)
|
.inspect_err(inspect_log)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,11 @@ pub(crate) async fn create_typing_event_route(
|
|||||||
// ping presence
|
// ping presence
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(&body.user_id, &ruma::presence::PresenceState::Online)
|
.maybe_ping_presence(
|
||||||
|
&body.user_id,
|
||||||
|
body.sender_device.as_deref(),
|
||||||
|
&ruma::presence::PresenceState::Online,
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(create_typing_event::v3::Response {})
|
Ok(create_typing_event::v3::Response {})
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ pub(crate) async fn delete_timezone_key_route(
|
|||||||
// Presence update
|
// Presence update
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(delete_timezone_key::unstable::Response {})
|
Ok(delete_timezone_key::unstable::Response {})
|
||||||
@@ -104,7 +104,7 @@ pub(crate) async fn set_timezone_key_route(
|
|||||||
// Presence update
|
// Presence update
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(set_timezone_key::unstable::Response {})
|
Ok(set_timezone_key::unstable::Response {})
|
||||||
@@ -170,7 +170,7 @@ pub(crate) async fn set_profile_field_route(
|
|||||||
// Presence update
|
// Presence update
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(set_profile_field::v3::Response {})
|
Ok(set_profile_field::v3::Response {})
|
||||||
@@ -224,7 +224,7 @@ pub(crate) async fn delete_profile_field_route(
|
|||||||
// Presence update
|
// Presence update
|
||||||
services
|
services
|
||||||
.presence
|
.presence
|
||||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(delete_profile_field::v3::Response {})
|
Ok(delete_profile_field::v3::Response {})
|
||||||
|
|||||||
@@ -4,11 +4,20 @@ mod presence;
|
|||||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use futures::{Stream, StreamExt, TryFutureExt, stream::FuturesUnordered};
|
use futures::{
|
||||||
|
Stream, StreamExt, TryFutureExt,
|
||||||
|
future::{OptionFuture, try_join},
|
||||||
|
stream::FuturesUnordered,
|
||||||
|
};
|
||||||
use loole::{Receiver, Sender};
|
use loole::{Receiver, Sender};
|
||||||
use ruma::{OwnedUserId, UInt, UserId, events::presence::PresenceEvent, presence::PresenceState};
|
use ruma::{
|
||||||
|
DeviceId, OwnedUserId, UInt, UserId, events::presence::PresenceEvent, presence::PresenceState,
|
||||||
|
};
|
||||||
use tokio::{sync::RwLock, time::sleep};
|
use tokio::{sync::RwLock, time::sleep};
|
||||||
use tuwunel_core::{Error, Result, checked, debug, debug_warn, error, result::LogErr, trace};
|
use tuwunel_core::{
|
||||||
|
Error, Result, checked, debug, debug_warn, error, result::LogErr, trace,
|
||||||
|
utils::future::OptionExt,
|
||||||
|
};
|
||||||
|
|
||||||
use self::{data::Data, presence::Presence};
|
use self::{data::Data, presence::Presence};
|
||||||
|
|
||||||
@@ -46,7 +55,7 @@ impl crate::Service for Service {
|
|||||||
// online
|
// online
|
||||||
self.unset_all_presence().await;
|
self.unset_all_presence().await;
|
||||||
_ = self
|
_ = self
|
||||||
.maybe_ping_presence(&self.services.globals.server_user, &PresenceState::Online)
|
.maybe_ping_presence(&self.services.globals.server_user, None, &PresenceState::Online)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let receiver = self.timer_channel.1.clone();
|
let receiver = self.timer_channel.1.clone();
|
||||||
@@ -73,7 +82,11 @@ impl crate::Service for Service {
|
|||||||
async fn interrupt(&self) {
|
async fn interrupt(&self) {
|
||||||
// set the server user as offline
|
// set the server user as offline
|
||||||
_ = self
|
_ = self
|
||||||
.maybe_ping_presence(&self.services.globals.server_user, &PresenceState::Offline)
|
.maybe_ping_presence(
|
||||||
|
&self.services.globals.server_user,
|
||||||
|
None,
|
||||||
|
&PresenceState::Offline,
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let (timer_sender, _) = &self.timer_channel;
|
let (timer_sender, _) = &self.timer_channel;
|
||||||
@@ -118,11 +131,12 @@ impl Service {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pings the presence of the given user in the given room, setting the
|
/// Pings the presence of the given user, setting the specified state. When
|
||||||
/// specified state.
|
/// device_id is supplied.
|
||||||
pub async fn maybe_ping_presence(
|
pub async fn maybe_ping_presence(
|
||||||
&self,
|
&self,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
|
device_id: Option<&DeviceId>,
|
||||||
new_state: &PresenceState,
|
new_state: &PresenceState,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
const REFRESH_TIMEOUT: u64 = 60 * 1000;
|
const REFRESH_TIMEOUT: u64 = 60 * 1000;
|
||||||
@@ -150,6 +164,14 @@ impl Service {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let update_device_seen: OptionFuture<_> = device_id
|
||||||
|
.map(|device_id| {
|
||||||
|
self.services
|
||||||
|
.users
|
||||||
|
.update_device_last_seen(user_id, device_id, None)
|
||||||
|
})
|
||||||
|
.into();
|
||||||
|
|
||||||
let status_msg = match last_presence {
|
let status_msg = match last_presence {
|
||||||
| Ok((_, ref presence)) => presence.content.status_msg.clone(),
|
| Ok((_, ref presence)) => presence.content.status_msg.clone(),
|
||||||
| Err(_) => Some(String::new()),
|
| Err(_) => Some(String::new()),
|
||||||
@@ -157,7 +179,16 @@ impl Service {
|
|||||||
|
|
||||||
let last_active_ago = UInt::new(0);
|
let last_active_ago = UInt::new(0);
|
||||||
let currently_active = *new_state == PresenceState::Online;
|
let currently_active = *new_state == PresenceState::Online;
|
||||||
self.set_presence(user_id, new_state, Some(currently_active), last_active_ago, status_msg)
|
let set_presence = self.set_presence(
|
||||||
|
user_id,
|
||||||
|
new_state,
|
||||||
|
Some(currently_active),
|
||||||
|
last_active_ago,
|
||||||
|
status_msg,
|
||||||
|
);
|
||||||
|
|
||||||
|
try_join(set_presence, update_device_seen.unwrap_or(Ok(())))
|
||||||
|
.map_ok(|_| ())
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -362,6 +362,26 @@ pub async fn remove_to_device_events<Until>(
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[implement(super::Service)]
|
||||||
|
pub async fn update_device_last_seen(
|
||||||
|
&self,
|
||||||
|
user_id: &UserId,
|
||||||
|
device_id: &DeviceId,
|
||||||
|
last_seen: Option<MilliSecondsSinceUnixEpoch>,
|
||||||
|
) -> Result {
|
||||||
|
let mut device = self
|
||||||
|
.get_device_metadata(user_id, device_id)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
device
|
||||||
|
.last_seen_ts
|
||||||
|
.replace(last_seen.unwrap_or_else(MilliSecondsSinceUnixEpoch::now));
|
||||||
|
|
||||||
|
self.put_device_metadata(user_id, false, &device);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[implement(super::Service)]
|
#[implement(super::Service)]
|
||||||
pub fn put_device_metadata(&self, user_id: &UserId, notify: bool, device: &Device) {
|
pub fn put_device_metadata(&self, user_id: &UserId, notify: bool, device: &Device) {
|
||||||
let key = (user_id, &device.device_id);
|
let key = (user_id, &device.device_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user