matrix_sdk/live_location_share.rs
1// Copyright 2024 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Types for live location sharing.
16//!
17//! Live location sharing allows users to share their real-time location with
18//! others in a room via [MSC3489](https://github.com/matrix-org/matrix-spec-proposals/pull/3489).
19use async_stream::stream;
20use futures_util::Stream;
21use ruma::{
22 events::{
23 beacon::OriginalSyncBeaconEvent, beacon_info::BeaconInfoEventContent,
24 location::LocationContent,
25 },
26 MilliSecondsSinceUnixEpoch, OwnedUserId, RoomId,
27};
28
29use crate::{event_handler::ObservableEventHandler, Client, Room};
30
31/// An observable live location.
32#[derive(Debug)]
33pub struct ObservableLiveLocation {
34 observable_room_events: ObservableEventHandler<(OriginalSyncBeaconEvent, Room)>,
35}
36
37impl ObservableLiveLocation {
38 /// Create a new `ObservableLiveLocation` for a particular room.
39 pub fn new(client: &Client, room_id: &RoomId) -> Self {
40 Self { observable_room_events: client.observe_room_events(room_id) }
41 }
42
43 /// Get a stream of [`LiveLocationShare`].
44 pub fn subscribe(&self) -> impl Stream<Item = LiveLocationShare> {
45 let stream = self.observable_room_events.subscribe();
46
47 stream! {
48 for await (event, room) in stream {
49 if event.sender != room.own_user_id() {
50 yield LiveLocationShare {
51 last_location: LastLocation {
52 location: event.content.location,
53 ts: event.origin_server_ts,
54 },
55 beacon_info: room
56 .get_user_beacon_info(&event.sender)
57 .await
58 .ok()
59 .map(|info| info.content),
60 user_id: event.sender,
61 };
62 }
63 }
64 }
65 }
66}
67
68/// Details of the last known location beacon.
69#[derive(Clone, Debug)]
70pub struct LastLocation {
71 /// The most recent location content of the user.
72 pub location: LocationContent,
73 /// The timestamp of when the location was updated.
74 pub ts: MilliSecondsSinceUnixEpoch,
75}
76
77/// Details of a users live location share.
78#[derive(Clone, Debug)]
79pub struct LiveLocationShare {
80 /// The user's last known location.
81 pub last_location: LastLocation,
82 /// Information about the associated beacon event.
83 pub beacon_info: Option<BeaconInfoEventContent>,
84 /// The user ID of the person sharing their live location.
85 pub user_id: OwnedUserId,
86}