Kopie van https://gitlab.com/studieverenigingvia/ict/centurion met een paar aanpassingen
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
centurion/backend/src/Room.ts

167 lines
3.3 KiB

import User from "./User";
import { getTimeline, getTimelineNames } from "./timeline";
import { getCurrentTime } from "./util";
export interface RoomOptions {
seekTime: number;
timelineName: string;
}
export interface TickerMessage {
user: User;
message: string;
}
// FIXME: dedupe with frontend
export interface SerializedRoom {
id: number;
userCount: number;
isLeader: boolean;
running: boolean;
startTime?: number;
seekTime: number;
timelineName: string;
readyToParticipate: boolean;
speedFactor: number;
ticker: string[];
users?: { id: string; readyToParticipate: boolean }[];
}
export default class Room {
id = 0;
users: User[] = [];
leader: User | null = null;
ticker: TickerMessage[] = [];
running = false;
startTime: number | undefined = undefined;
seekTime = 0;
timelineName = "Centurion";
// For debugging purposes
speedFactor = 1;
constructor(name: number) {
this.id = name;
}
serialize(user?: User) {
const obj: SerializedRoom = {
id: this.id,
userCount: this.users.length,
isLeader: this.leader === user,
running: this.running,
startTime: this.startTime,
timelineName: this.timelineName,
seekTime: this.seekTime,
readyToParticipate: this.getLeader()?.readyToParticipate || false,
speedFactor: this.speedFactor,
ticker: this.ticker.map((i) => i.message),
};
if (typeof user === "undefined" || this.leader === user) {
obj["users"] = this.users.map((u) => u.serialize());
}
return obj;
}
serializeTimeline() {
return getTimeline(this.timelineName);
}
sync() {
this.users.forEach((u) => u.sync());
}
async join(user: User) {
this.users.push(user);
await user.setRoom(this);
if (!this.hasLeader()) {
this.setLeader(user);
}
this.sync();
}
async leave(user: User) {
this.removeTickerMessageForUser(user);
this.users.splice(this.users.indexOf(user), 1);
await user.setRoom(null);
if (this.leader == user) {
this.setRandomLeader();
}
this.sync();
}
setOptions(options: { seekTime: number; timelineName: string }) {
this.seekTime = Math.max(0, Math.min(options.seekTime, 250 * 60 * 1000));
if (getTimelineNames().indexOf(options.timelineName) >= 0) {
this.timelineName = options.timelineName;
}
this.sync();
}
start() {
this.running = true;
this.startTime = getCurrentTime() - this.seekTime;
this.sync();
}
/**
*
* @returns {boolean}
*/
hasUsers() {
return this.users.length !== 0;
}
setRandomLeader() {
if (this.hasUsers()) {
this.leader = this.users[0];
}
}
hasLeader(): boolean {
return this.leader != null;
}
setLeader(user: User) {
this.leader = user;
}
getLeader(): User | null {
return this.leader;
}
submitTickerMessage(user: User, message: string) {
message = message.replace("\n", "");
this.removeTickerMessageForUser(user);
this.ticker.push({
user: user,
message: message,
});
this.sync();
}
removeTickerMessageForUser(user: User) {
let existing = -1;
for (let i = 0; i < this.ticker.length; i++) {
if (this.ticker[i].user === user) {
existing = i;
break;
}
}
if (existing >= 0) {
this.ticker.splice(existing, 1);
}
}
}