feat: migrate frontend from Vue 3 to React 18 with TanStack ecosystem
- Complete rewrite of frontend using React 18 + TypeScript in strict mode - Implement TanStack Router for file-based routing matching URL structure - Use TanStack Query for server state management with smart caching - Replace Pinia stores with React Context API for auth and UI state - Adopt Tailwind CSS + shadcn/ui components for consistent styling - Switch from pnpm to Bun for faster package management and builds - Configure Vite to support React, TypeScript, and modern tooling - Create frontend.go with Go embed package for embedding dist/ in binary - Implement comprehensive TypeScript interfaces (strict mode, no 'any' types) - Add dark mode support throughout with Tailwind CSS dark: classes - Set up i18n infrastructure (English translations included) - Remove all Vue 3 code, components, stores, CSS, and assets - Includes 18 new files with ~2000 lines of production-ready code
This commit is contained in:
64
frontend/src/api/preview.ts
Normal file
64
frontend/src/api/preview.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { API_BASE_URL } from "./client";
|
||||
|
||||
/**
|
||||
* Get preview URL for a file
|
||||
* @param path - File path
|
||||
* @param size - Preview size (128, 256, 512)
|
||||
*/
|
||||
export function getPreviewUrl(path: string, size: number = 256): string {
|
||||
const encodedPath = encodeURIComponent(path.slice(1)); // Remove leading slash
|
||||
return `${API_BASE_URL}/preview/${size}/${encodedPath}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file type is previewable
|
||||
*/
|
||||
export function isPreviewable(filename: string): boolean {
|
||||
const ext = filename.split(".").pop()?.toLowerCase() || "";
|
||||
const previewableTypes = [
|
||||
// Images
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"gif",
|
||||
"webp",
|
||||
"svg",
|
||||
"bmp",
|
||||
// Video
|
||||
"mp4",
|
||||
"webm",
|
||||
"ogv",
|
||||
// Audio
|
||||
"mp3",
|
||||
"wav",
|
||||
"ogg",
|
||||
// Documents
|
||||
"pdf",
|
||||
"txt",
|
||||
"md",
|
||||
"json",
|
||||
"xml",
|
||||
"html",
|
||||
"css",
|
||||
"js",
|
||||
];
|
||||
return previewableTypes.includes(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file type category
|
||||
*/
|
||||
export function getFileType(filename: string): "image" | "video" | "audio" | "document" | "unknown" {
|
||||
const ext = filename.split(".").pop()?.toLowerCase() || "";
|
||||
|
||||
const imageExts = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp"];
|
||||
const videoExts = ["mp4", "webm", "ogv"];
|
||||
const audioExts = ["mp3", "wav", "ogg"];
|
||||
const docExts = ["pdf", "txt", "md", "json", "xml", "html", "css", "js"];
|
||||
|
||||
if (imageExts.includes(ext)) return "image";
|
||||
if (videoExts.includes(ext)) return "video";
|
||||
if (audioExts.includes(ext)) return "audio";
|
||||
if (docExts.includes(ext)) return "document";
|
||||
return "unknown";
|
||||
}
|
||||
Reference in New Issue
Block a user