mirror of
https://github.com/p-stream/backend.git
synced 2026-03-11 09:45:34 +00:00
prettier
This commit is contained in:
parent
e37eeae3fe
commit
0cacd84da7
7 changed files with 3714 additions and 1344 deletions
|
|
@ -8,7 +8,7 @@ export async function sendPlayerStatus({
|
||||||
roomCode,
|
roomCode,
|
||||||
isHost,
|
isHost,
|
||||||
content,
|
content,
|
||||||
player
|
player,
|
||||||
}: {
|
}: {
|
||||||
userId: string;
|
userId: string;
|
||||||
roomCode: string;
|
roomCode: string;
|
||||||
|
|
@ -102,7 +102,6 @@ export async function getRoomStatuses(roomCode: string) {
|
||||||
*/
|
*/
|
||||||
export function ModifiedWebhookReporter() {
|
export function ModifiedWebhookReporter() {
|
||||||
// Example replacing the Discord webhook code
|
// Example replacing the Discord webhook code
|
||||||
|
|
||||||
/*
|
/*
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Skip if watch party is not enabled or no status
|
// Skip if watch party is not enabled or no status
|
||||||
|
|
@ -193,4 +192,4 @@ export function ModifiedWebhookReporter() {
|
||||||
isHost,
|
isHost,
|
||||||
]);
|
]);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4949
pnpm-lock.yaml
4949
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -12,26 +12,28 @@ Send a player status update.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"userId": "user123", // Required: User identifier
|
"userId": "user123", // Required: User identifier
|
||||||
"roomCode": "room456", // Required: Room code
|
"roomCode": "room456", // Required: Room code
|
||||||
"isHost": true, // Optional: Whether the user is the host
|
"isHost": true, // Optional: Whether the user is the host
|
||||||
"content": { // Optional: Content information
|
"content": {
|
||||||
|
// Optional: Content information
|
||||||
"title": "Movie Title",
|
"title": "Movie Title",
|
||||||
"type": "Movie", // "Movie", "TV Show", etc.
|
"type": "Movie", // "Movie", "TV Show", etc.
|
||||||
"tmdbId": 12345, // Optional: TMDB ID for the content
|
"tmdbId": 12345, // Optional: TMDB ID for the content
|
||||||
"seasonNumber": 1, // Optional: Season number (for TV shows)
|
"seasonNumber": 1, // Optional: Season number (for TV shows)
|
||||||
"episodeNumber": 3 // Optional: Episode number (for TV shows)
|
"episodeNumber": 3 // Optional: Episode number (for TV shows)
|
||||||
},
|
},
|
||||||
"player": { // Optional: Player state
|
"player": {
|
||||||
|
// Optional: Player state
|
||||||
"isPlaying": true,
|
"isPlaying": true,
|
||||||
"isPaused": false,
|
"isPaused": false,
|
||||||
"isLoading": false,
|
"isLoading": false,
|
||||||
"hasPlayedOnce": true,
|
"hasPlayedOnce": true,
|
||||||
"time": 120.5, // Current playback position in seconds
|
"time": 120.5, // Current playback position in seconds
|
||||||
"duration": 3600, // Total content duration in seconds
|
"duration": 3600, // Total content duration in seconds
|
||||||
"volume": 0.8, // Volume level (0-1)
|
"volume": 0.8, // Volume level (0-1)
|
||||||
"playbackRate": 1, // Playback speed
|
"playbackRate": 1, // Playback speed
|
||||||
"buffered": 180 // Buffered seconds
|
"buffered": 180 // Buffered seconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -41,7 +43,7 @@ Send a player status update.
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"success": true,
|
"success": true,
|
||||||
"timestamp": 1625097600000 // The timestamp assigned to this status update
|
"timestamp": 1625097600000 // The timestamp assigned to this status update
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -50,6 +52,7 @@ Send a player status update.
|
||||||
Get status updates for a specific user in a specific room.
|
Get status updates for a specific user in a specific room.
|
||||||
|
|
||||||
**Query Parameters:**
|
**Query Parameters:**
|
||||||
|
|
||||||
- `userId`: User identifier
|
- `userId`: User identifier
|
||||||
- `roomCode`: Room code
|
- `roomCode`: Room code
|
||||||
|
|
||||||
|
|
@ -94,6 +97,7 @@ Get status updates for a specific user in a specific room.
|
||||||
Get status updates for all users in a specific room.
|
Get status updates for all users in a specific room.
|
||||||
|
|
||||||
**Query Parameters:**
|
**Query Parameters:**
|
||||||
|
|
||||||
- `roomCode`: Room code
|
- `roomCode`: Room code
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
|
|
@ -120,7 +124,7 @@ Get status updates for all users in a specific room.
|
||||||
"isLoading": false,
|
"isLoading": false,
|
||||||
"hasPlayedOnce": true,
|
"hasPlayedOnce": true,
|
||||||
"time": 120.5,
|
"time": 120.5,
|
||||||
"duration": 3600,
|
"duration": 3600,
|
||||||
"volume": 0.8,
|
"volume": 0.8,
|
||||||
"playbackRate": 1,
|
"playbackRate": 1,
|
||||||
"buffered": 180
|
"buffered": 180
|
||||||
|
|
@ -140,4 +144,4 @@ Get status updates for all users in a specific room.
|
||||||
|
|
||||||
- Status data is automatically cleaned up if it's older than 1 minute
|
- Status data is automatically cleaned up if it's older than 1 minute
|
||||||
- The system keeps a maximum of 5 status updates per user per room
|
- The system keeps a maximum of 5 status updates per user per room
|
||||||
- Timestamps are in milliseconds since epoch (Unix timestamp)
|
- Timestamps are in milliseconds since epoch (Unix timestamp)
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,56 @@
|
||||||
import { defineEventHandler, getQuery, createError } from 'h3';
|
import { defineEventHandler, getQuery, createError } from 'h3';
|
||||||
import { playerStatusStore, CLEANUP_INTERVAL } from '~/utils/playerStatus';
|
import { playerStatusStore, CLEANUP_INTERVAL } from '~/utils/playerStatus';
|
||||||
|
|
||||||
export default defineEventHandler((event) => {
|
export default defineEventHandler(event => {
|
||||||
const query = getQuery(event);
|
const query = getQuery(event);
|
||||||
const userId = query.userId as string;
|
const userId = query.userId as string;
|
||||||
const roomCode = query.roomCode as string;
|
const roomCode = query.roomCode as string;
|
||||||
|
|
||||||
// If roomCode is provided but no userId, return all statuses for that room
|
// If roomCode is provided but no userId, return all statuses for that room
|
||||||
if (roomCode && !userId) {
|
if (roomCode && !userId) {
|
||||||
const cutoffTime = Date.now() - CLEANUP_INTERVAL;
|
const cutoffTime = Date.now() - CLEANUP_INTERVAL;
|
||||||
const roomStatuses: Record<string, any[]> = {};
|
const roomStatuses: Record<string, any[]> = {};
|
||||||
|
|
||||||
for (const [key, statuses] of playerStatusStore.entries()) {
|
for (const [key, statuses] of playerStatusStore.entries()) {
|
||||||
if (key.includes(`:${roomCode}`)) {
|
if (key.includes(`:${roomCode}`)) {
|
||||||
const userId = key.split(':')[0];
|
const userId = key.split(':')[0];
|
||||||
const recentStatuses = statuses.filter(status => status.timestamp >= cutoffTime);
|
const recentStatuses = statuses.filter(status => status.timestamp >= cutoffTime);
|
||||||
|
|
||||||
if (recentStatuses.length > 0) {
|
if (recentStatuses.length > 0) {
|
||||||
roomStatuses[userId] = recentStatuses;
|
roomStatuses[userId] = recentStatuses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
roomCode,
|
roomCode,
|
||||||
users: roomStatuses
|
users: roomStatuses,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If both userId and roomCode are provided, return status for that user in that room
|
// If both userId and roomCode are provided, return status for that user in that room
|
||||||
if (userId && roomCode) {
|
if (userId && roomCode) {
|
||||||
const key = `${userId}:${roomCode}`;
|
const key = `${userId}:${roomCode}`;
|
||||||
const statuses = playerStatusStore.get(key) || [];
|
const statuses = playerStatusStore.get(key) || [];
|
||||||
|
|
||||||
// Remove statuses older than 15 minutes
|
// Remove statuses older than 15 minutes
|
||||||
const cutoffTime = Date.now() - CLEANUP_INTERVAL;
|
const cutoffTime = Date.now() - CLEANUP_INTERVAL;
|
||||||
const recentStatuses = statuses.filter(status => status.timestamp >= cutoffTime);
|
const recentStatuses = statuses.filter(status => status.timestamp >= cutoffTime);
|
||||||
|
|
||||||
if (recentStatuses.length !== statuses.length) {
|
if (recentStatuses.length !== statuses.length) {
|
||||||
playerStatusStore.set(key, recentStatuses);
|
playerStatusStore.set(key, recentStatuses);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userId,
|
userId,
|
||||||
roomCode,
|
roomCode,
|
||||||
statuses: recentStatuses
|
statuses: recentStatuses,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If neither is provided, return error
|
// If neither is provided, return error
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
statusMessage: 'Missing required query parameters: roomCode and/or userId'
|
statusMessage: 'Missing required query parameters: roomCode and/or userId',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import { defineEventHandler, readBody, createError } from 'h3';
|
import { defineEventHandler, readBody, createError } from 'h3';
|
||||||
import { playerStatusStore, PlayerStatus } from '~/utils/playerStatus';
|
import { playerStatusStore, PlayerStatus } from '~/utils/playerStatus';
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async event => {
|
||||||
const body = await readBody(event);
|
const body = await readBody(event);
|
||||||
|
|
||||||
if (!body || !body.userId || !body.roomCode) {
|
if (!body || !body.userId || !body.roomCode) {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
statusMessage: 'Missing required fields: userId, roomCode'
|
statusMessage: 'Missing required fields: userId, roomCode',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const status: PlayerStatus = {
|
const status: PlayerStatus = {
|
||||||
userId: body.userId,
|
userId: body.userId,
|
||||||
roomCode: body.roomCode,
|
roomCode: body.roomCode,
|
||||||
|
|
@ -22,7 +22,7 @@ export default defineEventHandler(async (event) => {
|
||||||
seasonId: body.content?.seasonId,
|
seasonId: body.content?.seasonId,
|
||||||
episodeId: body.content?.episodeId,
|
episodeId: body.content?.episodeId,
|
||||||
seasonNumber: body.content?.seasonNumber,
|
seasonNumber: body.content?.seasonNumber,
|
||||||
episodeNumber: body.content?.episodeNumber
|
episodeNumber: body.content?.episodeNumber,
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
isPlaying: body.player?.isPlaying || false,
|
isPlaying: body.player?.isPlaying || false,
|
||||||
|
|
@ -35,19 +35,19 @@ export default defineEventHandler(async (event) => {
|
||||||
playbackRate: body.player?.playbackRate || 1,
|
playbackRate: body.player?.playbackRate || 1,
|
||||||
buffered: body.player?.buffered || 0,
|
buffered: body.player?.buffered || 0,
|
||||||
},
|
},
|
||||||
timestamp: Date.now()
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const key = `${status.userId}:${status.roomCode}`;
|
const key = `${status.userId}:${status.roomCode}`;
|
||||||
const existingStatuses = playerStatusStore.get(key) || [];
|
const existingStatuses = playerStatusStore.get(key) || [];
|
||||||
|
|
||||||
// Add new status and keep only the last 5 statuses
|
// Add new status and keep only the last 5 statuses
|
||||||
existingStatuses.push(status);
|
existingStatuses.push(status);
|
||||||
if (existingStatuses.length > 5) {
|
if (existingStatuses.length > 5) {
|
||||||
existingStatuses.shift();
|
existingStatuses.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
playerStatusStore.set(key, existingStatuses);
|
playerStatusStore.set(key, existingStatuses);
|
||||||
|
|
||||||
return { success: true, timestamp: status.timestamp };
|
return { success: true, timestamp: status.timestamp };
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,14 @@ const progressMetaSchema = z.object({
|
||||||
const progressItemSchema = z.object({
|
const progressItemSchema = z.object({
|
||||||
meta: progressMetaSchema,
|
meta: progressMetaSchema,
|
||||||
tmdbId: z.string().transform(val => val || randomUUID()),
|
tmdbId: z.string().transform(val => val || randomUUID()),
|
||||||
duration: z.number().min(0).transform(n => Math.round(n)),
|
duration: z
|
||||||
watched: z.number().min(0).transform(n => Math.round(n)),
|
.number()
|
||||||
|
.min(0)
|
||||||
|
.transform(n => Math.round(n)),
|
||||||
|
watched: z
|
||||||
|
.number()
|
||||||
|
.min(0)
|
||||||
|
.transform(n => Math.round(n)),
|
||||||
seasonId: z.string().optional(),
|
seasonId: z.string().optional(),
|
||||||
episodeId: z.string().optional(),
|
episodeId: z.string().optional(),
|
||||||
seasonNumber: z.number().optional(),
|
seasonNumber: z.number().optional(),
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ export const CLEANUP_INTERVAL = 1 * 60 * 1000;
|
||||||
// Clean up old status entries
|
// Clean up old status entries
|
||||||
function cleanupOldStatuses() {
|
function cleanupOldStatuses() {
|
||||||
const cutoffTime = Date.now() - CLEANUP_INTERVAL;
|
const cutoffTime = Date.now() - CLEANUP_INTERVAL;
|
||||||
|
|
||||||
for (const [key, statuses] of playerStatusStore.entries()) {
|
for (const [key, statuses] of playerStatusStore.entries()) {
|
||||||
const filteredStatuses = statuses.filter(status => status.timestamp >= cutoffTime);
|
const filteredStatuses = statuses.filter(status => status.timestamp >= cutoffTime);
|
||||||
|
|
||||||
if (filteredStatuses.length === 0) {
|
if (filteredStatuses.length === 0) {
|
||||||
playerStatusStore.delete(key);
|
playerStatusStore.delete(key);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -49,4 +49,4 @@ function cleanupOldStatuses() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule cleanup every 1 minute
|
// Schedule cleanup every 1 minute
|
||||||
setInterval(cleanupOldStatuses, 1 * 60 * 1000);
|
setInterval(cleanupOldStatuses, 1 * 60 * 1000);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue