96 lines
2.2 KiB
Rust
96 lines
2.2 KiB
Rust
use std::{collections::HashMap, sync::Arc};
|
|
|
|
use axum::extract::ws::{Message, WebSocket};
|
|
use dashmap::DashMap;
|
|
use futures::{stream::SplitSink, SinkExt};
|
|
use once_cell::sync::Lazy;
|
|
use tokio::sync::{Mutex, MutexGuard};
|
|
use uuid::Uuid;
|
|
|
|
use crate::sources::MediaSource;
|
|
|
|
#[derive(Clone)]
|
|
pub struct RoomRef {
|
|
room: Arc<Mutex<Room>>,
|
|
}
|
|
|
|
impl RoomRef {
|
|
fn new(room: Room) -> Self {
|
|
RoomRef {
|
|
room: Arc::new(Mutex::new(room)),
|
|
}
|
|
}
|
|
|
|
pub async fn get(&self) -> MutexGuard<Room> {
|
|
self.room.lock().await
|
|
}
|
|
|
|
pub async fn add_member(&self, member: Member) {
|
|
let mut room = self.room.lock().await;
|
|
room.members.insert(member.id, member);
|
|
}
|
|
|
|
pub async fn broadcast(&self, message: Message) {
|
|
let mut room = self.room.lock().await;
|
|
for member in room.members.values_mut() {
|
|
member.send(message.clone()).await
|
|
}
|
|
}
|
|
|
|
pub async fn list_chat_members(&self) -> Vec<ChatIdentity> {
|
|
let room = self.room.lock().await;
|
|
room.members
|
|
.values()
|
|
.flat_map(|m| &m.chat_identity)
|
|
.cloned()
|
|
.collect()
|
|
}
|
|
}
|
|
|
|
static ROOMS: Lazy<DashMap<Uuid, RoomRef>> = Lazy::new(DashMap::new);
|
|
|
|
pub async fn create_room(playlist: Vec<MediaSource>) -> RoomRef {
|
|
let id = Uuid::new_v4();
|
|
let room = Room {
|
|
id,
|
|
playlist,
|
|
currently_playing: 0,
|
|
members: HashMap::new(),
|
|
};
|
|
|
|
let room_ref = RoomRef::new(room);
|
|
ROOMS.insert(id, room_ref.clone());
|
|
room_ref
|
|
}
|
|
|
|
pub async fn find_room(id: Uuid) -> Option<RoomRef> {
|
|
ROOMS.get(&id).as_deref().cloned()
|
|
}
|
|
|
|
pub struct Room {
|
|
pub id: Uuid,
|
|
pub playlist: Vec<MediaSource>,
|
|
pub currently_playing: usize,
|
|
pub members: HashMap<Uuid, Member>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct ChatIdentity {
|
|
pub nickname: String,
|
|
pub color: String,
|
|
}
|
|
|
|
pub struct Member {
|
|
pub id: Uuid,
|
|
pub chat_identity: Option<ChatIdentity>,
|
|
pub connections: Vec<SplitSink<WebSocket, Message>>,
|
|
}
|
|
|
|
impl Member {
|
|
pub async fn send(&mut self, message: Message) {
|
|
for conn in self.connections.iter_mut() {
|
|
let _ = conn.send(message.clone()).await;
|
|
}
|
|
}
|
|
}
|