Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export const load: PageLoad = async ({ fetch, params, url }) => {
console.error('Failed to fetch file info for meta tags', e);
}

const ogUrl = new URL('/og/download', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'download');
ogUrl.searchParams.set('filename', filename);
if (fileSizeStr) {
ogUrl.searchParams.set('size', fileSizeStr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export const load: PageLoad = async ({ fetch, params, url }) => {
console.error('Failed to fetch file info for meta tags', e);
}

const ogUrl = new URL('/og/view', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'view');
ogUrl.searchParams.set('filename', filename);
if (fileSizeStr) {
ogUrl.searchParams.set('size', fileSizeStr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { definePageMetaTags } from 'svelte-meta-tags';
import type { PageLoad } from './$types';

export const load: PageLoad = ({ url }) => {
const ogUrl = new URL('/og/speedtest', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'speedtest');
ogUrl.searchParams.set('title', 'Network Speedtest');
ogUrl.searchParams.set(
'description',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export const load: PageLoad = async ({ parent, fetch, url }) => {

prefetch({ queryClient: queryClient, fetch });

const ogUrl = new URL('/og/upload', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'upload');
ogUrl.searchParams.set('title', 'Upload Files');
ogUrl.searchParams.set(
'description',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ export enum UploadStage {
Stage_3
}

const uploadStages = new Set<UploadStage>(
Object.values(UploadStage).filter((value): value is UploadStage => typeof value === 'number')
);

export const isWhichUploadStage = (value: unknown): value is UploadStage => {
return (
value === UploadStage.Stage_1 || value === UploadStage.Stage_2 || value === UploadStage.Stage_3
);
return typeof value === 'number' && uploadStages.has(value);
};
3 changes: 2 additions & 1 deletion src/frontend/src/routes/(needs_onboarding)/login/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import type { PageLoad } from './$types';
import { schema } from './schema';

export const load: PageLoad = async ({ url }) => {
const ogUrl = new URL('/og/login', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'login');
ogUrl.searchParams.set('title', 'Welcome Back');
ogUrl.searchParams.set(
'description',
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/routes/informations/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { definePageMetaTags } from 'svelte-meta-tags';
import type { PageLoad } from './$types';

export const load: PageLoad = async ({ url }) => {
const ogUrl = new URL('/og/info', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'info');
ogUrl.searchParams.set('label', 'INSTANCE OVERVIEW');
ogUrl.searchParams.set('title', 'System Information');
ogUrl.searchParams.set(
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/routes/informations/backend/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { definePageMetaTags } from 'svelte-meta-tags';
import type { PageLoad } from './$types';

export const load: PageLoad = async ({ fetch, parent, url }) => {
const ogUrl = new URL('/og/info', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'info');
ogUrl.searchParams.set('label', 'BACKEND INFRASTRUCTURE');
ogUrl.searchParams.set('title', 'Chithi Backend');
ogUrl.searchParams.set(
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/routes/informations/frontend/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { definePageMetaTags } from 'svelte-meta-tags';
import type { PageLoad } from './$types';

export const load: PageLoad = async ({ url }) => {
const ogUrl = new URL('/og/info', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'info');
ogUrl.searchParams.set('label', 'SYSTEM INFORMATION');
ogUrl.searchParams.set('title', 'Chithi Instance');
ogUrl.searchParams.set(
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/routes/informations/statistics/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { definePageMetaTags } from 'svelte-meta-tags';
import type { PageLoad } from './$types';

export const load: PageLoad = async ({ fetch, parent, url }) => {
const ogUrl = new URL('/og/info', url.origin);
const ogUrl = new URL('/og', url.origin);
ogUrl.searchParams.set('type', 'info');
ogUrl.searchParams.set('label', 'PERFORMANCE METRICS');
ogUrl.searchParams.set('title', 'Instance Statistics');
ogUrl.searchParams.set(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,29 @@ import ImageResponse from 'takumi-js/response';
import type { RequestEvent } from './$types';
import Component from './Component.svelte';

export async function GET({ url }: RequestEvent) {
function getRequestDomain(url: URL, request: Request) {
const forwardedHost = request.headers.get('x-forwarded-host');
const host = forwardedHost?.split(',')[0]?.trim() ?? request.headers.get('host');
if (host) {
return host.replace(/:\d+$/, '');
}

return url.hostname;
}

export async function GET({ url, request }: RequestEvent) {
const domain = getRequestDomain(url, request);
const rawKind = url.searchParams.get('type');
const kind = rawKind?.trim().toLowerCase() || 'base';
const { body, head } = await render(Component, {
props: {
kind,
label: url.searchParams.get('label'),
title: url.searchParams.get('title'),
description: url.searchParams.get('description')
description: url.searchParams.get('description'),
filename: url.searchParams.get('filename'),
size: url.searchParams.get('size'),
domain
}
});

Expand Down
99 changes: 99 additions & 0 deletions src/frontend/src/routes/og/Component.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<script lang="ts">
import OGLayout from './OGLayout.svelte';

type OgConfig = {
label: string;
title?: string;
description?: string;
footerTags?: string[];
labelFromQuery?: boolean;
usesFileMeta?: boolean;
};

const OG_CONFIG: Record<string, OgConfig> = {
base: {
label: 'Private by design',
title: 'Chithi',
description: 'Encrypted file sharing with end-to-end privacy and auto-expiring links',
footerTags: ['End-to-end encryption', 'Auto-expiring links', 'Zero-knowledge transfer']
},
login: {
label: 'Authentication',
title: 'Welcome Back',
description: 'Log in to your Chithi instance to manage and share encrypted files.'
},
once: {
label: 'Burn After Reading',
title: 'One-time View',
description: 'View your encrypted file once. The link will expire immediately after.'
},
speedtest: {
label: 'Performance',
title: 'Network Speedtest',
description: 'Test your connection speed to the Chithi server for optimal transfers.'
},
upload: {
label: 'Share Securely',
title: 'Upload Files',
description: 'Securely upload and share encrypted files with auto-expiring links.'
},
info: {
label: 'Information',
title: 'Chithi Instance',
description: 'System information, statistics, and metadata for this instance.',
labelFromQuery: true
},
download: {
label: 'Ready to download',
usesFileMeta: true
},
view: {
label: 'Ready to view',
usesFileMeta: true
}
};

let { kind, label, title, description, filename, size, domain } = $props<{
kind?: string | null;
label?: string | null;
title?: string | null;
description?: string | null;
filename?: string | null;
size?: string | null;
domain?: string | null;
}>();

const normalizedKind = $derived(kind?.trim().toLowerCase() || 'base');
const config = $derived(OG_CONFIG[normalizedKind as keyof typeof OG_CONFIG] ?? OG_CONFIG.base);

const displayLabel = $derived(
config.labelFromQuery ? label?.trim() || config.label : config.label
);
const displayTitle = $derived(
(() => {
if (config.usesFileMeta) {
return (filename?.trim() || 'Encrypted File').slice(0, 42);
}

return (title?.trim() || config.title || 'Chithi').slice(0, 42);
})()
);
const displaySubtitle = $derived(
(() => {
if (config.usesFileMeta) {
const displaySize = size?.trim() || 'Unknown size';
return `Size: ${displaySize}`;
}

return (description?.trim() || config.description || '').slice(0, 90);
})()
);
</script>

<OGLayout
label={displayLabel}
title={displayTitle}
subtitle={displaySubtitle}
{domain}
footerTags={config.footerTags}
/>
16 changes: 16 additions & 0 deletions src/frontend/src/routes/og/OGLayout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@
import logo from '$lib/assets/logo.svg?raw';

let {
domain,
label,
title,
subtitle,
footerTags = ['End-to-end encryption', 'Auto-expiring links', 'Zero-knowledge']
} = $props<{
domain?: string;
label: string;
title: string;
subtitle: string;
footerTags?: string[];
}>();

const RTL_CHARACTERS = /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/;
const displayDomain = $derived(domain?.trim() || '');
const isRtl = $derived(RTL_CHARACTERS.test(`${label} ${title} ${subtitle}`));
const direction = $derived(isRtl ? 'rtl' : 'ltr');
const domainAlignClass = $derived(isRtl ? 'ml-auto text-right' : 'mr-auto text-left');
</script>

<div
Expand All @@ -26,6 +34,14 @@
<div
class="absolute -right-50 -bottom-50 flex h-150 w-150 rounded-full bg-[rgba(214,16,179,0.15)] blur-[120px]"
></div>
<div class="absolute top-10 right-24 left-24 z-10 flex">
<div
class={`flex items-center text-[20px] font-semibold text-[#e5e7eb] ${domainAlignClass}`}
dir={direction}
>
{displayDomain}
</div>
</div>

<!-- Main Content Row -->
<div class="relative z-10 flex flex-row items-center">
Expand Down
28 changes: 0 additions & 28 deletions src/frontend/src/routes/og/base/+server.ts

This file was deleted.

23 changes: 0 additions & 23 deletions src/frontend/src/routes/og/base/Component.svelte

This file was deleted.

28 changes: 0 additions & 28 deletions src/frontend/src/routes/og/download/+server.ts

This file was deleted.

13 changes: 0 additions & 13 deletions src/frontend/src/routes/og/download/Component.svelte

This file was deleted.

19 changes: 0 additions & 19 deletions src/frontend/src/routes/og/info/Component.svelte

This file was deleted.

Loading
Loading