158 lines
4.6 KiB
TypeScript
158 lines
4.6 KiB
TypeScript
import { FastifyReply, FastifyRequest } from 'fastify';
|
|
import * as roomService from './rooms.service';
|
|
import { getUserById } from '../user/user.service';
|
|
import { openTunnel } from "./tunnel.manager";
|
|
|
|
interface CreateRoomBody {
|
|
name: string;
|
|
password?: string;
|
|
expose?: boolean;
|
|
}
|
|
|
|
export async function createRoom(req: any, reply: FastifyReply) {
|
|
try {
|
|
const { name, password, expose } = req.body as CreateRoomBody;
|
|
const userId = req.user?.id;
|
|
|
|
if (!userId) {
|
|
return reply.code(401).send({ error: "Authentication required to create room" });
|
|
}
|
|
|
|
if (!name || name.trim().length === 0) {
|
|
return reply.code(400).send({ error: "Room name is required" });
|
|
}
|
|
|
|
const user = await getUserById(userId);
|
|
if (!user) {
|
|
return reply.code(404).send({ error: "User not found" });
|
|
}
|
|
|
|
const host = {
|
|
id: `user_${userId}`,
|
|
username: user.username,
|
|
avatar: user.profile_picture_url || undefined,
|
|
isHost: true,
|
|
isGuest: false,
|
|
userId
|
|
};
|
|
|
|
let publicUrl: string | undefined;
|
|
|
|
if (expose) {
|
|
publicUrl = await openTunnel();
|
|
}
|
|
|
|
const room = roomService.createRoom(
|
|
name,
|
|
host,
|
|
password,
|
|
!!expose,
|
|
publicUrl
|
|
);
|
|
|
|
if (expose && publicUrl) {
|
|
room.publicUrl = `${publicUrl}/room?id=${room.id}`;
|
|
}
|
|
|
|
return reply.send({
|
|
success: true,
|
|
room: {
|
|
id: room.id,
|
|
name: room.name,
|
|
hasPassword: !!room.password,
|
|
userCount: room.users.size,
|
|
exposed: room.exposed,
|
|
publicUrl: room.publicUrl
|
|
}
|
|
});
|
|
} catch (err) {
|
|
console.error("Create Room Error:", err);
|
|
return reply.code(500).send({ error: "Failed to create room" });
|
|
}
|
|
}
|
|
|
|
export async function getRooms(req: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const rooms = roomService.getAllRooms();
|
|
|
|
const roomList = rooms.map((room) => ({
|
|
id: room.id,
|
|
name: room.name,
|
|
host: room.host.username,
|
|
userCount: room.users.size,
|
|
hasPassword: !!room.password,
|
|
currentlyWatching: room.currentVideo ? {
|
|
animeId: room.currentVideo.animeId,
|
|
episode: room.currentVideo.episode
|
|
} : null
|
|
}));
|
|
|
|
return reply.send({ rooms: roomList });
|
|
} catch (err) {
|
|
console.error("Get Rooms Error:", err);
|
|
return reply.code(500).send({ error: "Failed to retrieve rooms" });
|
|
}
|
|
}
|
|
|
|
export async function getRoom(req: FastifyRequest, reply: FastifyReply) {
|
|
try {
|
|
const { id } = req.params as { id: string };
|
|
const room = roomService.getRoom(id);
|
|
|
|
if (!room) {
|
|
return reply.code(404).send({ error: "Room not found" });
|
|
}
|
|
|
|
return reply.send({
|
|
room: {
|
|
id: room.id,
|
|
name: room.name,
|
|
host: {
|
|
username: room.host.username,
|
|
avatar: room.host.avatar
|
|
},
|
|
users: Array.from(room.users.values()).map(u => ({
|
|
id: u.id,
|
|
username: u.username,
|
|
avatar: u.avatar,
|
|
isHost: u.isHost,
|
|
isGuest: u.isGuest
|
|
})),
|
|
hasPassword: !!room.password,
|
|
currentVideo: room.currentVideo,
|
|
exposed: room.exposed,
|
|
publicUrl: room.publicUrl
|
|
}
|
|
});
|
|
} catch (err) {
|
|
console.error("Get Room Error:", err);
|
|
return reply.code(500).send({ error: "Failed to retrieve room" });
|
|
}
|
|
}
|
|
|
|
export async function deleteRoom(req: any, reply: FastifyReply) {
|
|
try {
|
|
const { id } = req.params as { id: string };
|
|
const userId = req.user?.id;
|
|
|
|
if (!userId) {
|
|
return reply.code(401).send({ error: "Authentication required" });
|
|
}
|
|
|
|
const room = roomService.getRoom(id);
|
|
if (!room) {
|
|
return reply.code(404).send({ error: "Room not found" });
|
|
}
|
|
|
|
if (room.host.userId !== userId) {
|
|
return reply.code(403).send({ error: "Only the host can delete the room" });
|
|
}
|
|
|
|
roomService.deleteRoom(id);
|
|
|
|
return reply.send({ success: true });
|
|
} catch (err) {
|
|
console.error("Delete Room Error:", err);
|
|
return reply.code(500).send({ error: "Failed to delete room" });
|
|
}
|
|
} |