Skip to content

Commit 11fd91a

Browse files
committed
feat: add lazy loading for Xen TG App pages
1 parent dde6a8d commit 11fd91a

File tree

12 files changed

+127
-94
lines changed

12 files changed

+127
-94
lines changed

apps/xen-tg-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"react": "^19.1.0",
2424
"react-dom": "^19.1.0",
2525
"react-error-boundary": "^6.0.0",
26-
"react-router": "^7.0.2",
26+
"react-router": "^7.7.0",
2727
"tailwind-merge": "^3.2.0",
2828
"tailwindcss": "^4.1.4",
2929
"tw-animate-css": "^1.2.5"

apps/xen-tg-app/src/App.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ import { Link } from 'react-router'
22
import SettingsIcon from './assets/settings'
33
import XEN_IMAGE from '/xen.png'
44
import Capabilities from './components/Capabilities'
5-
import Layout from './components/Layout'
65
import Wallet from './components/Wallet'
76

87
const App = () => {
98
const tg = window.Telegram.WebApp
109
if (!tg.isExpanded) tg.expand()
1110

1211
return (
13-
<Layout>
12+
<>
1413
<Link
1514
to="/settings"
1615
className="absolute top-5 right-4 rounded-full border border-(--color-opposite-text) bg-(--color-light-white-bg) p-2 backdrop-blur-3xl backdrop-opacity-80 dark:border-(--color-main-text)/30"
@@ -22,7 +21,7 @@ const App = () => {
2221
</div>
2322
<Wallet />
2423
<Capabilities />
25-
</Layout>
24+
</>
2625
)
2726
}
2827

apps/xen-tg-app/src/components/Agent.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FC, useEffect, useMemo } from 'react'
1+
import { FC, startTransition, useEffect, useMemo } from 'react'
22
// import UnlinkOutlineIcon from '../assets/unlink-outline'
33
import ArrowForwardIcon from '@/assets/arrow-forward'
44
import { Switch } from '@/components/ui/switch'
@@ -54,7 +54,8 @@ const Agent: FC<TAgentProps> = ({ capabilitiy }) => {
5454

5555
const action = useMemo(() => {
5656
// ToDo: better to use capabilitiy.id?
57-
if (capabilitiy.name === 'news-monitor') return () => navigate('/news-monitor')
57+
if (capabilitiy.name === 'news-monitor')
58+
return () => startTransition(() => navigate('/news-monitor'))
5859
}, [capabilitiy, navigate])
5960

6061
const handleChangeStatus = () =>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const Fallback = () => (
2+
<div className="flex h-[calc(100vh-100px)] w-screen items-center justify-center">
3+
<span className="h-12 w-12 animate-spin rounded-[24px] border-6 border-(--color-opposite-text) border-b-(--color-gray-text)"></span>
4+
</div>
5+
)
6+
7+
export default Fallback

apps/xen-tg-app/src/components/History.tsx

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { API_URL } from '@/env'
22
import { useQuery } from '@tanstack/react-query'
33
import { THistoryNote } from '../types'
4-
// import Header from './Header'
54
import { Accordion } from '@/components/ui/accordion'
65
import { useGoBack } from '@/hooks/useGoBack'
76
import HistoryNote from './HistoryNote'
8-
import Layout from './Layout'
97

108
const queryFn = (name: string, params?: { [key: string]: string | number }) => async () => {
119
if (!window.Telegram.WebApp.initData) {
@@ -43,20 +41,18 @@ const History = () => {
4341
useGoBack()
4442

4543
return (
46-
<Layout>
47-
<div className="z-1 flex w-full flex-col items-center justify-between gap-2.5 rounded-xl border border-(--color-opposite-text) p-2.5 backdrop-blur-3xl backdrop-opacity-80 dark:border-(--color-main-text)/30">
48-
<div className="my-1.5 flex w-full items-center justify-between">
49-
<h1 className="text-center text-2xl font-bold">History</h1>
50-
</div>
51-
{history ? (
52-
<Accordion type="multiple" className="flex w-full flex-col gap-2.5">
53-
{history.items.map((note) => (
54-
<HistoryNote key={note.id} note={note} />
55-
))}
56-
</Accordion>
57-
) : null}
44+
<div className="z-1 flex w-full flex-col items-center justify-between gap-2.5 rounded-xl border border-(--color-opposite-text) p-2.5 backdrop-blur-3xl backdrop-opacity-80 dark:border-(--color-main-text)/30">
45+
<div className="my-1.5 flex w-full items-center justify-between">
46+
<h1 className="text-center text-2xl font-bold">History</h1>
5847
</div>
59-
</Layout>
48+
{history ? (
49+
<Accordion type="multiple" className="flex w-full flex-col gap-2.5">
50+
{history.items.map((note) => (
51+
<HistoryNote key={note.id} note={note} />
52+
))}
53+
</Accordion>
54+
) : null}
55+
</div>
6056
)
6157
}
6258

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import { FullscreenProvider } from '@/hooks/fullscreen-provider.tsx'
22
import { ThemeProvider } from '@/hooks/theme-provider'
3-
import { FC } from 'react'
3+
import { Outlet } from 'react-router'
44
import AnimatedBackground from './AnimatedBackground'
5+
import { ErrorBoundary } from 'react-error-boundary'
56

6-
const Layout: FC<{ children: React.ReactNode }> = ({ children }) => (
7-
<ThemeProvider storageKey="vite-ui-theme">
8-
<FullscreenProvider storageKey="fullscreen-enabled">
9-
<div
10-
style={{ marginTop: 'calc(var(--tg-content-safe-area-inset-top) + 12px)' }}
11-
className="relative flex w-full max-w-xl min-w-80 flex-col items-center justify-center gap-5 px-2.5 py-5 text-(--color-main-text)"
12-
>
13-
<AnimatedBackground />
14-
{children}
15-
</div>
16-
</FullscreenProvider>
17-
</ThemeProvider>
7+
const Layout = () => (
8+
<ErrorBoundary fallback={<p>⚠️Something went wrong</p>}>
9+
<ThemeProvider storageKey="vite-ui-theme">
10+
<FullscreenProvider storageKey="fullscreen-enabled">
11+
<div
12+
style={{ marginTop: 'calc(var(--tg-content-safe-area-inset-top) + 12px)' }}
13+
className="relative flex w-full max-w-xl min-w-80 flex-col items-center justify-center gap-5 px-2.5 py-5 text-(--color-main-text)"
14+
>
15+
<AnimatedBackground />
16+
<Outlet />
17+
</div>
18+
</FullscreenProvider>
19+
</ThemeProvider>
20+
</ErrorBoundary>
1821
)
1922

2023
export default Layout

apps/xen-tg-app/src/components/Memories.tsx

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { API_URL } from '@/env'
22
import { useGoBack } from '@/hooks/useGoBack'
33
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
44
import { TMemory } from '../types'
5-
import Layout from './Layout'
65
import Memory from './Memory'
76
import Spinner from './Spinner'
87

@@ -74,21 +73,19 @@ const Memories = () => {
7473
useGoBack()
7574

7675
return (
77-
<Layout>
78-
<div className="z-1 flex w-full flex-col items-center justify-between gap-2.5 rounded-xl border border-(--color-opposite-text) p-2.5 backdrop-blur-3xl backdrop-opacity-80 dark:border-(--color-main-text)/30">
79-
<div className="my-1.5 flex w-full items-center justify-between">
80-
<h1 className="text-center text-2xl font-bold">{`Memories (${memories?.total ?? '-'})`}</h1>
81-
<button
82-
className="flex w-16 cursor-pointer items-center justify-center py-1.5 text-(--color-gray-text) transition hover:not-disabled:text-(--color-main-text) hover:disabled:cursor-default"
83-
onClick={() => handleDeleteAll.mutate()}
84-
disabled={!memories || !memories.total}
85-
>
86-
{handleDeleteAll.isPending ? <Spinner /> : 'Clear all'}
87-
</button>
88-
</div>
89-
{memories?.items.map((memory) => <Memory key={memory.data} memory={memory} />)}
76+
<div className="z-1 flex w-full flex-col items-center justify-between gap-2.5 rounded-xl border border-(--color-opposite-text) p-2.5 backdrop-blur-3xl backdrop-opacity-80 dark:border-(--color-main-text)/30">
77+
<div className="my-1.5 flex w-full items-center justify-between">
78+
<h1 className="text-center text-2xl font-bold">{`Memories (${memories?.total ?? '-'})`}</h1>
79+
<button
80+
className="flex w-16 cursor-pointer items-center justify-center py-1.5 text-(--color-gray-text) transition hover:not-disabled:text-(--color-main-text) hover:disabled:cursor-default"
81+
onClick={() => handleDeleteAll.mutate()}
82+
disabled={!memories || !memories.total}
83+
>
84+
{handleDeleteAll.isPending ? <Spinner /> : 'Clear all'}
85+
</button>
9086
</div>
91-
</Layout>
87+
{memories?.items.map((memory) => <Memory key={memory.data} memory={memory} />)}
88+
</div>
9289
)
9390
}
9491

apps/xen-tg-app/src/components/NewsMonitor.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tansta
88
import { formatDistance } from 'date-fns'
99
import { useEffect, useRef, useState } from 'react'
1010
import { TSubscription } from '../types'
11-
import Layout from './Layout'
1211
import { NewSubscription, Subscription } from './NewsSource'
1312
import Spinner from './Spinner'
1413

@@ -190,7 +189,7 @@ const NewsMonitor = () => {
190189
useGoBack()
191190

192191
return (
193-
<Layout>
192+
<>
194193
<div className="z-1 flex w-full items-center justify-between gap-2.5 px-2.5">
195194
<div className="flex items-center gap-2.5">
196195
<div className="flex h-6 w-6 items-center justify-between">
@@ -265,7 +264,7 @@ const NewsMonitor = () => {
265264
</div>
266265
) : null}
267266
</div>
268-
</Layout>
267+
</>
269268
)
270269
}
271270

apps/xen-tg-app/src/components/Settings.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import { useQuery } from '@tanstack/react-query'
44
import { Link } from 'react-router'
55
import { TMemory } from '../types'
66
import DeveloperMode from './DeveloperMode'
7-
import Layout from './Layout'
7+
import FullscreenMode from './FullscreenMode'
88
import ThemeButton from './ThemeButton'
99
import Warnings from './Warnings'
10-
import FullscreenMode from './FullscreenMode'
1110

1211
const queryFn = (name: string, params?: { [key: string]: string | number }) => async () => {
1312
if (!window.Telegram.WebApp.initData) {
@@ -45,7 +44,7 @@ const Settings = () => {
4544
useGoBack()
4645

4746
return (
48-
<Layout>
47+
<>
4948
<ThemeButton />
5049
<FullscreenMode />
5150
<DeveloperMode />
@@ -63,7 +62,7 @@ const Settings = () => {
6362
</div>
6463
</div>
6564
<Warnings />
66-
</Layout>
65+
</>
6766
)
6867
}
6968

apps/xen-tg-app/src/hooks/useGoBack.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { useEffect } from 'react'
1+
import { startTransition, useEffect } from 'react'
22
import { useNavigate } from 'react-router'
33

44
export const useGoBack = () => {
55
const navigate = useNavigate()
66
const { BackButton } = window.Telegram.WebApp
77
useEffect(() => {
88
BackButton.show()
9-
const backRoute = () => navigate(-1)
9+
const backRoute = () => startTransition(() => navigate(-1))
1010
BackButton.onClick(backRoute)
1111
return () => {
1212
BackButton.hide()

0 commit comments

Comments
 (0)