use async_stream::stream;
use futures_util::Stream;
use ruma::{
MilliSecondsSinceUnixEpoch, OwnedUserId, RoomId,
events::{
beacon::OriginalSyncBeaconEvent, beacon_info::BeaconInfoEventContent,
location::LocationContent,
},
};
use crate::{Client, Room, event_handler::ObservableEventHandler};
#[derive(Debug)]
pub struct ObservableLiveLocation {
observable_room_events: ObservableEventHandler<(OriginalSyncBeaconEvent, Room)>,
}
impl ObservableLiveLocation {
pub fn new(client: &Client, room_id: &RoomId) -> Self {
Self { observable_room_events: client.observe_room_events(room_id) }
}
pub fn subscribe(&self) -> impl Stream<Item = LiveLocationShare> + use<> {
let stream = self.observable_room_events.subscribe();
stream! {
for await (event, room) in stream {
if event.sender != room.own_user_id() {
yield LiveLocationShare {
last_location: LastLocation {
location: event.content.location,
ts: event.origin_server_ts,
},
beacon_info: room
.get_user_beacon_info(&event.sender)
.await
.ok()
.map(|info| info.content),
user_id: event.sender,
};
}
}
}
}
}
#[derive(Clone, Debug)]
pub struct LastLocation {
pub location: LocationContent,
pub ts: MilliSecondsSinceUnixEpoch,
}
#[derive(Clone, Debug)]
pub struct LiveLocationShare {
pub last_location: LastLocation,
pub beacon_info: Option<BeaconInfoEventContent>,
pub user_id: OwnedUserId,
}