Skip to content

Commit 8f12621

Browse files
committed
feat: new view file showing options
1 parent e5ee076 commit 8f12621

File tree

5 files changed

+132
-47
lines changed

5 files changed

+132
-47
lines changed

src/components/pages/files/tags/TagPill.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { Tag } from '@/lib/db/models/tag';
21
import { Pill, isLightColor } from '@mantine/core';
32

43
export default function TagPill({
54
tag,
65
...other
76
}: {
8-
tag: Tag | null;
7+
tag: { color: string; name: string } | null;
98
withRemoveButton?: boolean;
109
onRemove?: () => void;
1110
}) {

src/components/pages/settings/parts/SettingsFileView.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export default function SettingsFileView() {
4949
embedColor: user?.view.embedColor ?? '',
5050
align: user?.view.align ?? 'left',
5151
showMimetype: user?.view.showMimetype ?? false,
52+
showTags: user?.view.showTags ?? false,
53+
showFolder: user?.view.showFolder ?? false,
5254
},
5355
});
5456

@@ -63,6 +65,8 @@ export default function SettingsFileView() {
6365
embedColor: values.embedColor.trim() || null,
6466
align: values.align,
6567
showMimetype: values.showMimetype,
68+
showTags: values.showTags,
69+
showFolder: values.showFolder,
6670
};
6771

6872
const { data, error } = await fetchApi<Response['/api/user']>('/api/user', 'PATCH', {
@@ -110,6 +114,20 @@ export default function SettingsFileView() {
110114
disabled={!form.values.enabled}
111115
{...form.getInputProps('showMimetype', { type: 'checkbox' })}
112116
/>
117+
118+
<Switch
119+
label='Show tags'
120+
description="Show the file's tags in the view-route"
121+
disabled={!form.values.enabled}
122+
{...form.getInputProps('showTags', { type: 'checkbox' })}
123+
/>
124+
125+
<Switch
126+
label='Show folder'
127+
description='Show the name/link of the folder if possible in the view-route'
128+
disabled={!form.values.enabled}
129+
{...form.getInputProps('showFolder', { type: 'checkbox' })}
130+
/>
113131
</SimpleGrid>
114132

115133
<Textarea

src/lib/db/models/user.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ export const userViewSchema = z
4343
enabled: z.boolean().nullish(),
4444
align: z.enum(['left', 'center', 'right']).nullish(),
4545
showMimetype: z.boolean().nullish(),
46+
showTags: z.boolean().nullish(),
47+
showFolder: z.boolean().nullish(),
4648
content: z.string().nullish(),
4749
embed: z.boolean().nullish(),
4850
embedTitle: z.string().nullish(),

src/pages/view/[id].tsx

Lines changed: 105 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import DashboardFileType from '@/components/file/DashboardFileType';
2+
import TagPill from '@/components/pages/files/tags/TagPill';
23
import { isCode } from '@/lib/code';
34
import { config as zConfig } from '@/lib/config';
45
import { verifyPassword } from '@/lib/crypto';
@@ -13,6 +14,7 @@ import { readThemes } from '@/lib/theme/file';
1314
import { formatRootUrl } from '@/lib/url';
1415
import {
1516
ActionIcon,
17+
Anchor,
1618
Box,
1719
Button,
1820
Center,
@@ -22,9 +24,10 @@ import {
2224
Paper,
2325
PasswordInput,
2426
Text,
27+
Tooltip,
2528
TypographyStylesProvider,
2629
} from '@mantine/core';
27-
import { IconDownload, IconInfoCircleFilled } from '@tabler/icons-react';
30+
import { IconDownload, IconExternalLink, IconInfoCircleFilled } from '@tabler/icons-react';
2831
import { sanitize } from 'isomorphic-dompurify';
2932
import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
3033
import Head from 'next/head';
@@ -76,32 +79,47 @@ export default function ViewFileId({
7679
<meta
7780
property='og:title'
7881
content={
79-
parseString(user.view.embedTitle, { file: file as File, user: user as User, ...metrics }) ?? ''
82+
parseString(user.view.embedTitle, {
83+
file: file as unknown as File,
84+
user: user as User,
85+
...metrics,
86+
}) ?? ''
8087
}
8188
/>
8289
)}
8390
{user?.view!.embedDescription && user?.view.embed && (
8491
<meta
8592
property='og:description'
8693
content={
87-
parseString(user.view.embedDescription, { file: file as File, user: user as User, ...metrics }) ??
88-
''
94+
parseString(user.view.embedDescription, {
95+
file: file as unknown as File,
96+
user: user as User,
97+
...metrics,
98+
}) ?? ''
8999
}
90100
/>
91101
)}
92102
{user?.view!.embedSiteName && user?.view.embed && (
93103
<meta
94104
property='og:site_name'
95105
content={
96-
parseString(user.view.embedSiteName, { file: file as File, user: user as User, ...metrics }) ?? ''
106+
parseString(user.view.embedSiteName, {
107+
file: file as unknown as File,
108+
user: user as User,
109+
...metrics,
110+
}) ?? ''
97111
}
98112
/>
99113
)}
100114
{user?.view!.embedColor && user?.view.embed && (
101115
<meta
102116
property='theme-color'
103117
content={
104-
parseString(user.view.embedColor, { file: file as File, user: user as User, ...metrics }) ?? ''
118+
parseString(user.view.embedColor, {
119+
file: file as unknown as File,
120+
user: user as User,
121+
...metrics,
122+
}) ?? ''
105123
}
106124
/>
107125
)}
@@ -212,7 +230,7 @@ export default function ViewFileId({
212230
dangerouslySetInnerHTML={{
213231
__html: sanitize(
214232
parseString(user.view.content, {
215-
file: file as File,
233+
file: file as unknown as File,
216234
link: {
217235
returned: `${host}${formatRootUrl(filesRoute ?? '/u', file.name!)}`,
218236
raw: `${host}/raw/${file.name}`,
@@ -233,49 +251,74 @@ export default function ViewFileId({
233251

234252
{file.name!.endsWith('.md') || file.name!.endsWith('.tex') ? (
235253
<Paper m='md' p='md' withBorder>
236-
<DashboardFileType file={file as File} password={pw} show code={code} />
254+
<DashboardFileType file={file as unknown as File} password={pw} show code={code} />
237255
</Paper>
238256
) : (
239257
<Box m='sm'>
240-
<DashboardFileType file={file as File} password={pw} show code={code} />
258+
<DashboardFileType file={file as unknown as File} password={pw} show code={code} />
241259
</Box>
242260
)}
243261
</>
244262
) : (
245263
<>
246264
{meta}
247265
<Center h='100%'>
248-
<Paper
249-
m='md'
250-
p='md'
251-
shadow='md'
252-
radius='md'
253-
withBorder
254-
>
266+
<Paper m='md' p='md' shadow='md' radius='md' withBorder>
255267
<Group justify='space-between' mb='sm'>
256268
<Group>
257269
<Text size='lg' fw={700} display='flex'>
258-
{file.name}
270+
{file.name}{' '}
259271
</Text>
272+
{user?.view!.showTags && (
273+
<Group gap={4}>{file.tags?.map((tag) => <TagPill key={tag.id} tag={tag} />)}</Group>
274+
)}
275+
{user?.view!.showFolder &&
276+
file.Folder &&
277+
(file.Folder.public ? (
278+
<Tooltip label='View folder'>
279+
<Anchor component={Link} ml='sm' href={`/folder/${file.Folder.id}`}>
280+
{file.Folder.name}
281+
</Anchor>
282+
</Tooltip>
283+
) : (
284+
<Text ml='sm' size='sm' c='dimmed'>
285+
{file.Folder.name}
286+
</Text>
287+
))}
260288
{user?.view!.showMimetype && (
261289
<Text size='sm' c='dimmed' ml='sm' style={{ alignSelf: 'center' }}>
262290
{file.type}
263291
</Text>
264292
)}
265293
</Group>
266294

267-
<ActionIcon
268-
size='md'
269-
variant='outline'
270-
component={Link}
271-
href={`/raw/${file.name}?download=true${pw ? `&pw=${pw}` : ''}`}
272-
target='_blank'
273-
>
274-
<IconDownload size='1rem' />
275-
</ActionIcon>
295+
<ActionIcon.Group>
296+
<Tooltip label='View raw file'>
297+
<ActionIcon
298+
size='md'
299+
variant='outline'
300+
component={Link}
301+
href={`/raw/${file.name}${pw ? `?pw=${pw}` : ''}`}
302+
target='_blank'
303+
>
304+
<IconExternalLink size='1rem' />
305+
</ActionIcon>
306+
</Tooltip>
307+
<Tooltip label='Download file'>
308+
<ActionIcon
309+
size='md'
310+
variant='outline'
311+
component={Link}
312+
href={`/raw/${file.name}?download=true${pw ? `&pw=${pw}` : ''}`}
313+
target='_blank'
314+
>
315+
<IconDownload size='1rem' />
316+
</ActionIcon>
317+
</Tooltip>
318+
</ActionIcon.Group>
276319
</Group>
277320

278-
<DashboardFileType allowZoom file={file as File} password={pw} show />
321+
<DashboardFileType allowZoom file={file as unknown as File} password={pw} show />
279322

280323
{mounted && user?.view!.content && (
281324
<TypographyStylesProvider>
@@ -285,7 +328,7 @@ export default function ViewFileId({
285328
dangerouslySetInnerHTML={{
286329
__html: sanitize(
287330
parseString(user?.view.content, {
288-
file: file as File,
331+
file: file as unknown as File,
289332
link: {
290333
returned: `${host}${formatRootUrl(filesRoute ?? '/u', file.name!)}`,
291334
raw: `${host}/raw/${file.name}`,
@@ -308,8 +351,40 @@ export default function ViewFileId({
308351
);
309352
}
310353

354+
const getFile = async (id: string) =>
355+
prisma.file.findFirst({
356+
where: {
357+
name: id as string,
358+
},
359+
select: {
360+
...fileSelect,
361+
password: true,
362+
userId: true,
363+
thumbnail: {
364+
select: {
365+
path: true,
366+
},
367+
},
368+
tags: {
369+
select: {
370+
id: true,
371+
name: true,
372+
color: true,
373+
},
374+
},
375+
376+
Folder: {
377+
select: {
378+
id: true,
379+
public: true,
380+
name: true,
381+
},
382+
},
383+
},
384+
});
385+
311386
export const getServerSideProps: GetServerSideProps<{
312-
file: Partial<File>;
387+
file: Partial<NonNullable<Awaited<ReturnType<typeof getFile>>>>;
313388
password?: boolean;
314389
pw?: string;
315390
code: boolean;
@@ -325,22 +400,7 @@ export const getServerSideProps: GetServerSideProps<{
325400
const { config: libConfig, reloadSettings } = await import('@/lib/config');
326401
if (!libConfig) await reloadSettings();
327402

328-
const file = await prisma.file.findFirst({
329-
where: {
330-
name: id as string,
331-
},
332-
select: {
333-
...fileSelect,
334-
password: true,
335-
userId: true,
336-
tags: false,
337-
thumbnail: {
338-
select: {
339-
path: true,
340-
},
341-
},
342-
},
343-
});
403+
const file = await getFile(id as string);
344404
if (!file || !file.userId) return { notFound: true };
345405

346406
if (file.maxViews && file.views >= file.maxViews) return { notFound: true };

src/server/routes/api/user/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ type Body = {
2424
enabled?: boolean;
2525
align?: 'left' | 'center' | 'right';
2626
showMimetype?: boolean;
27+
showTags?: boolean;
28+
showFolder?: boolean;
2729
};
2830
};
2931

@@ -73,6 +75,10 @@ export default fastifyPlugin(
7375
...(req.body.view.showMimetype !== undefined && {
7476
showMimetype: req.body.view.showMimetype || false,
7577
}),
78+
...(req.body.view.showTags !== undefined && { showTags: req.body.view.showTags || false }),
79+
...(req.body.view.showFolder !== undefined && {
80+
showFolder: req.body.view.showFolder || false,
81+
}),
7682
},
7783
}),
7884
},

0 commit comments

Comments
 (0)