v2: global player, infinite scroll, image picker, threaded comments

This commit is contained in:
khannurien
2026-03-21 13:55:22 +00:00
parent be426eb150
commit 7c098e7c4c
48 changed files with 4346 additions and 711 deletions

View File

@@ -10,6 +10,7 @@ export interface RichContent {
description?: string;
thumbnailUrl?: string;
videoId?: string;
embedUrl?: string;
}
export interface Dump {
@@ -25,6 +26,8 @@ export interface Dump {
fileMime?: string;
fileSize?: number;
voteCount: number;
commentCount: number;
isPrivate: boolean;
}
/**
@@ -130,6 +133,12 @@ export interface APIFailure {
export type APIResponse<T> = APISuccess<T> | APIFailure;
export interface PaginatedData<T> {
items: T[];
total: number;
hasMore: boolean;
}
export class APIException extends Error {
readonly code: APIErrorCode;
readonly status: number;
@@ -141,6 +150,34 @@ export class APIException extends Error {
}
}
/**
* Comments
*/
export interface Comment {
id: string;
dumpId: string;
userId: string;
parentId?: string;
body: string;
createdAt: Date;
deleted: boolean;
authorUsername: string;
authorAvatarMime?: string;
}
export interface CreateCommentRequest {
body: string;
parentId?: string;
}
export function isCreateCommentRequest(obj: unknown): obj is CreateCommentRequest {
if (!obj || typeof obj !== "object") return false;
const o = obj as Record<string, unknown>;
return typeof o.body === "string" && (o.body as string).trim().length > 0 &&
(!("parentId" in o) || typeof o.parentId === "string" || o.parentId === null);
}
/**
* Playlists
*/
@@ -216,6 +253,7 @@ export function isReorderPlaylistRequest(
export interface CreateUrlDumpRequest {
url: string;
comment?: string;
isPrivate?: boolean;
}
export function isCreateUrlDumpRequest(
@@ -225,12 +263,14 @@ export function isCreateUrlDumpRequest(
typeof obj === "object" &&
"url" in obj && typeof obj.url === "string" &&
(!("comment" in obj) ||
typeof obj.comment === "string" || obj.comment === null);
typeof obj.comment === "string" || obj.comment === null) &&
(!("isPrivate" in obj) || typeof obj.isPrivate === "boolean");
}
export interface UpdateDumpRequest {
url?: string;
comment?: string;
isPrivate?: boolean;
}
export function isUpdateDumpRequest(obj: unknown): obj is UpdateDumpRequest {
@@ -238,7 +278,8 @@ export function isUpdateDumpRequest(obj: unknown): obj is UpdateDumpRequest {
typeof obj === "object" &&
(!("url" in obj) || typeof obj.url === "string" || obj.url === null) &&
(!("comment" in obj) ||
typeof obj.comment === "string" || obj.comment === null);
typeof obj.comment === "string" || obj.comment === null) &&
(!("isPrivate" in obj) || typeof obj.isPrivate === "boolean");
}
/**