1
1
import type { ClusterModel , ManagedPackage , ManagedUser , ManagedVersion , Paginated , Provider } from '@/bindings.gen' ;
2
+ import Modal from '@/components/overlay/Modal' ;
2
3
import { useBrowserContext , usePackageData , usePackageVersions } from '@/hooks/useBrowser' ;
3
4
import { useClusters } from '@/hooks/useCluster' ;
4
5
import { bindings } from '@/main' ;
5
6
import { abbreviateNumber , formatAsRelative , PROVIDERS } from '@/utils' ;
6
7
import { useCommand } from '@onelauncher/common' ;
7
- import { Button , Show , Tooltip } from '@onelauncher/common/components' ;
8
+ import { Button , Popup , Show , Tooltip } from '@onelauncher/common/components' ;
8
9
import { createFileRoute , Link } from '@tanstack/react-router' ;
9
10
import { openUrl } from '@tauri-apps/plugin-opener' ;
10
11
import { CalendarIcon , ChevronDownIcon , ChevronUpIcon , ClockRewindIcon , Download01Icon , File02Icon , LinkExternal01Icon } from '@untitled-theme/icons-react' ;
11
12
import { createContext , useContext , useEffect , useMemo , useRef , useState } from 'react' ;
12
- import { Collection , ListBox , ListBoxItem , Popover , Select } from 'react-aria-components' ;
13
+ import { Collection , ListBox , ListBoxItem , Popover , Pressable , Select , Tab , TabList , TabPanel , Tabs } from 'react-aria-components' ;
14
+ import Markdown from 'react-markdown' ;
15
+ import rehypeRaw from 'rehype-raw' ;
13
16
14
17
export const Route = createFileRoute ( '/app/browser/package/$provider/$slug' ) ( {
15
18
component : RouteComponent ,
@@ -33,7 +36,7 @@ function RouteComponent() {
33
36
const { provider, slug } = Route . useParams ( ) ;
34
37
if ( ! includes ( PROVIDERS , provider ) )
35
38
throw new Error ( 'Invalid provider' ) ;
36
- const packageData = usePackageData ( provider , slug , { } , `getPackage. ${ provider } . ${ slug } ` ) ;
39
+ const packageData = usePackageData ( provider , slug , { } ) ;
37
40
const browserContext = useBrowserContext ( ) ;
38
41
const { data : versions } = usePackageVersions ( provider , slug , {
39
42
mc_versions : browserContext . cluster ? [ browserContext . cluster . mc_version ] : null ,
@@ -47,17 +50,39 @@ function RouteComponent() {
47
50
< div className = "h-full flex flex-1 flex-row items-start gap-x-4" >
48
51
< BrowserSidebar package = { packageData . data ! } />
49
52
50
- < div className = "min-h-full flex flex-1 flex-col items-start gap-y-4 pb-8" >
51
- < div className = "flex flex-none flex-row gap-x-1 rounded-lg bg-component-bg p-1" >
52
- < Link params = { { provider, slug } } to = "/app/browser/package/$provider/$slug" > About</ Link >
53
- < Link params = { { provider, slug } } to = "/app/browser/package/$provider/$slug" > Versions</ Link >
54
-
53
+ < Tabs className = "min-h-full flex flex-1 flex-col items-start gap-y-4 pb-8" >
54
+ < TabList className = "flex flex-none flex-row gap-x-1 rounded-lg bg-component-bg p-1 w-min" >
55
+ < Tab className = "uppercase p-2.5 text-trim rounded-md selected:bg-component-bg-pressed disabled:hidden" id = "about" > About</ Tab >
56
+ < Tab className = "uppercase p-2.5 text-trim rounded-md selected:bg-component-bg-pressed disabled:hidden" id = "versions" > Versions</ Tab >
57
+ < Tab className = "uppercase p-2.5 text-trim rounded-md selected:bg-component-bg-pressed disabled:hidden" id = "gallery" isDisabled = { packageData . data ?. gallery . length === 0 } > Gallery</ Tab >
58
+ </ TabList >
59
+ < div className = "h-full min-h-full flex-1 w-full rounded-lg bg-component-bg p-3" >
60
+ < TabPanel className = "prose prose-invert prose-sm max-w-none" id = "about" >
61
+ < Markdown rehypePlugins = { [ rehypeRaw ] } > { packageData . data ?. body } </ Markdown >
62
+ </ TabPanel >
63
+ < TabPanel id = "versions" >
64
+ versions
65
+ </ TabPanel >
66
+ < TabPanel id = "gallery" className = "flex flex-wrap gap-2 justify-center" >
67
+
68
+ { packageData . data ?. gallery . map ( item => (
69
+ < Modal . Trigger key = { item . url } >
70
+ < Pressable >
71
+ < div className = 'rounded-md overflow-hidden bg-component-bg-pressed outline-0 h-64 flex flex-col relative' >
72
+ < img className = 'h-full' src = { item . thumbnail_url } />
73
+ { item . title && < div className = 'absolute w-full bottom-0 bg-component-bg-disabled/80 p-2' > { item . title } </ div > }
74
+ </ div >
75
+ </ Pressable >
76
+ < Modal className = 'w-full' >
77
+ < img className = 'rounded-xl' src = { item . url } />
78
+ </ Modal >
79
+ </ Modal . Trigger >
80
+ ) ) }
81
+
82
+ </ TabPanel >
55
83
</ div >
84
+ </ Tabs >
56
85
57
- < div className = "h-full min-h-full w-full flex-1" >
58
-
59
- </ div >
60
- </ div >
61
86
</ div >
62
87
</ Show >
63
88
</ PackageContext >
@@ -74,7 +99,7 @@ function BrowserSidebar({ package: pkg }: { package: ManagedPackage }) {
74
99
75
100
return (
76
101
< div className = "sticky top-0 z-1 max-w-60 min-w-54 flex flex-col gap-y-4" >
77
- < div className = "min-h-72 flex flex-col overflow-hidden rounded-lg bg-component-bg" >
102
+ < div className = "flex flex-col overflow-hidden rounded-lg bg-component-bg" >
78
103
< div className = "relative h-28 flex items-center justify-center overflow-hidden" >
79
104
< img alt = { `Icon for ${ pkg . name } ` } className = "absolute z-0 max-w-none w-7/6 blur-xl" src = { pkg . icon_url || '' } />
80
105
< img alt = { `Icon for ${ pkg . name } ` } className = "relative z-1 aspect-ratio-square w-2/5 rounded-md image-render-auto" src = { pkg . icon_url || '' } />
0 commit comments