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
|
||||
services
|
||||
.presence
|
||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
||||
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||
.await?;
|
||||
|
||||
Ok(set_display_name::v3::Response {})
|
||||
@@ -149,7 +149,7 @@ pub(crate) async fn set_avatar_url_route(
|
||||
// Presence update
|
||||
services
|
||||
.presence
|
||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
||||
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
|
||||
@@ -93,7 +93,11 @@ pub(crate) async fn set_read_marker_route(
|
||||
|
||||
services
|
||||
.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
|
||||
.ok();
|
||||
}
|
||||
@@ -165,7 +169,11 @@ pub(crate) async fn create_receipt_route(
|
||||
|
||||
services
|
||||
.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
|
||||
.ok();
|
||||
},
|
||||
|
||||
@@ -130,7 +130,7 @@ pub(crate) async fn sync_events_route(
|
||||
|
||||
let ping_presence = services
|
||||
.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)
|
||||
.ok();
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ pub(crate) async fn sync_events_v5_route(
|
||||
let conn = conn_val.lock();
|
||||
let ping_presence = services
|
||||
.presence
|
||||
.maybe_ping_presence(sender_user, &request.set_presence)
|
||||
.maybe_ping_presence(sender_user, Some(sender_device), &request.set_presence)
|
||||
.inspect_err(inspect_log)
|
||||
.ok();
|
||||
|
||||
|
||||
@@ -66,7 +66,11 @@ pub(crate) async fn create_typing_event_route(
|
||||
// ping presence
|
||||
services
|
||||
.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?;
|
||||
|
||||
Ok(create_typing_event::v3::Response {})
|
||||
|
||||
@@ -76,7 +76,7 @@ pub(crate) async fn delete_timezone_key_route(
|
||||
// Presence update
|
||||
services
|
||||
.presence
|
||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
||||
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||
.await?;
|
||||
|
||||
Ok(delete_timezone_key::unstable::Response {})
|
||||
@@ -104,7 +104,7 @@ pub(crate) async fn set_timezone_key_route(
|
||||
// Presence update
|
||||
services
|
||||
.presence
|
||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
||||
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||
.await?;
|
||||
|
||||
Ok(set_timezone_key::unstable::Response {})
|
||||
@@ -170,7 +170,7 @@ pub(crate) async fn set_profile_field_route(
|
||||
// Presence update
|
||||
services
|
||||
.presence
|
||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
||||
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||
.await?;
|
||||
|
||||
Ok(set_profile_field::v3::Response {})
|
||||
@@ -224,7 +224,7 @@ pub(crate) async fn delete_profile_field_route(
|
||||
// Presence update
|
||||
services
|
||||
.presence
|
||||
.maybe_ping_presence(&body.user_id, &PresenceState::Online)
|
||||
.maybe_ping_presence(&body.user_id, body.sender_device.as_deref(), &PresenceState::Online)
|
||||
.await?;
|
||||
|
||||
Ok(delete_profile_field::v3::Response {})
|
||||
|
||||
@@ -4,11 +4,20 @@ mod presence;
|
||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||
|
||||
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 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 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};
|
||||
|
||||
@@ -46,7 +55,7 @@ impl crate::Service for Service {
|
||||
// online
|
||||
self.unset_all_presence().await;
|
||||
_ = self
|
||||
.maybe_ping_presence(&self.services.globals.server_user, &PresenceState::Online)
|
||||
.maybe_ping_presence(&self.services.globals.server_user, None, &PresenceState::Online)
|
||||
.await;
|
||||
|
||||
let receiver = self.timer_channel.1.clone();
|
||||
@@ -73,7 +82,11 @@ impl crate::Service for Service {
|
||||
async fn interrupt(&self) {
|
||||
// set the server user as offline
|
||||
_ = self
|
||||
.maybe_ping_presence(&self.services.globals.server_user, &PresenceState::Offline)
|
||||
.maybe_ping_presence(
|
||||
&self.services.globals.server_user,
|
||||
None,
|
||||
&PresenceState::Offline,
|
||||
)
|
||||
.await;
|
||||
|
||||
let (timer_sender, _) = &self.timer_channel;
|
||||
@@ -118,11 +131,12 @@ impl Service {
|
||||
.await
|
||||
}
|
||||
|
||||
/// Pings the presence of the given user in the given room, setting the
|
||||
/// specified state.
|
||||
/// Pings the presence of the given user, setting the specified state. When
|
||||
/// device_id is supplied.
|
||||
pub async fn maybe_ping_presence(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
device_id: Option<&DeviceId>,
|
||||
new_state: &PresenceState,
|
||||
) -> Result {
|
||||
const REFRESH_TIMEOUT: u64 = 60 * 1000;
|
||||
@@ -150,6 +164,14 @@ impl Service {
|
||||
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 {
|
||||
| Ok((_, ref presence)) => presence.content.status_msg.clone(),
|
||||
| Err(_) => Some(String::new()),
|
||||
@@ -157,7 +179,16 @@ impl Service {
|
||||
|
||||
let last_active_ago = UInt::new(0);
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -362,6 +362,26 @@ pub async fn remove_to_device_events<Until>(
|
||||
.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)]
|
||||
pub fn put_device_metadata(&self, user_id: &UserId, notify: bool, device: &Device) {
|
||||
let key = (user_id, &device.device_id);
|
||||
|
||||
Reference in New Issue
Block a user