Files
libnovel/ui-v2/src/routes/users/[username]/+page.server.ts
Admin 5825b859b7
All checks were successful
Release / Scraper / Test (push) Successful in 10s
Release / UI / Build (push) Successful in 26s
Release / v2 / Build ui-v2 (push) Successful in 17s
Release / Scraper / Docker (push) Successful in 47s
Release / UI / Docker (push) Successful in 56s
CI / Scraper / Lint (pull_request) Successful in 7s
CI / Scraper / Test (pull_request) Successful in 8s
CI / UI / Build (pull_request) Successful in 16s
CI / Scraper / Docker Push (pull_request) Has been skipped
CI / UI / Docker Push (pull_request) Has been skipped
Release / v2 / Docker / ui-v2 (push) Successful in 56s
Release / v2 / Test backend (push) Successful in 4m35s
iOS CI / Build (pull_request) Successful in 4m28s
Release / v2 / Docker / backend (push) Successful in 1m29s
Release / v2 / Docker / runner (push) Successful in 1m39s
iOS CI / Test (pull_request) Successful in 9m51s
feat: add v2 stack (backend, runner, ui-v2) with release workflow
- backend/: Go API server and runner binaries with PocketBase + MinIO storage
- ui-v2/: SvelteKit frontend rewrite
- docker-compose-new.yml: compose file for the v2 stack
- .gitea/workflows/release-v2.yaml: CI/CD for backend, runner, and ui-v2 Docker Hub images
- scripts/pb-init.sh: migrate from wget to curl, add superuser bootstrap for fresh installs
- .env.example: document DOCKER_BUILDKIT=1 for Colima users
2026-03-15 19:32:40 +05:00

60 lines
1.8 KiB
TypeScript

import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import {
getPublicProfile,
getSubscription,
getUserPublicLibrary,
getUserCurrentlyReading
} from '$lib/server/pocketbase';
import { presignAvatarUrl } from '$lib/server/minio';
import { log } from '$lib/server/logger';
export const load: PageServerLoad = async ({ params, locals }) => {
const { username } = params;
const profile = await getPublicProfile(username).catch(() => null);
if (!profile) error(404, `User "${username}" not found`);
// Resolve avatar
let avatarUrl: string | null = null;
if (profile.avatar_url) {
avatarUrl = await presignAvatarUrl(profile.id).catch(() => null);
}
// Subscription state for the logged-in visitor
let isSubscribed = false;
const isSelf = locals.user?.id === profile.id;
if (locals.user && !isSelf) {
const sub = await getSubscription(locals.user.id, profile.id).catch(() => null);
isSubscribed = !!sub;
}
// Load public library + currently reading in parallel
const [library, currentlyReading] = await Promise.all([
getUserPublicLibrary(profile.id).catch((e) => {
log.error('users/profile', 'getUserPublicLibrary failed', { username, err: String(e) });
return [] as Awaited<ReturnType<typeof getUserPublicLibrary>>;
}),
getUserCurrentlyReading(profile.id).catch((e) => {
log.error('users/profile', 'getUserCurrentlyReading failed', { username, err: String(e) });
return [] as Awaited<ReturnType<typeof getUserCurrentlyReading>>;
})
]);
return {
profile: {
id: profile.id,
username: profile.username,
created: profile.created,
followerCount: profile.followerCount,
followingCount: profile.followingCount
},
avatarUrl,
isSubscribed,
isSelf,
isLoggedIn: !!locals.user,
library,
currentlyReading
};
};