Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
115d1bac
Commit
115d1bac
authored
Dec 28, 2025
by
Johnny
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: replace MemoSkeleton with a new Skeleton component for improved loading states
parent
792d58b7
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
132 additions
and
112 deletions
+132
-112
index.tsx
web/src/components/MemoEditor/index.tsx
+0
-2
MemoSkeleton.tsx
web/src/components/MemoSkeleton.tsx
+0
-56
PagedMemoList.tsx
web/src/components/PagedMemoList/PagedMemoList.tsx
+4
-10
Skeleton.tsx
web/src/components/Skeleton.tsx
+80
-0
Spinner.tsx
web/src/components/Spinner.tsx
+19
-0
RootLayout.tsx
web/src/layouts/RootLayout.tsx
+2
-2
main.tsx
web/src/main.tsx
+8
-10
AuthCallback.tsx
web/src/pages/AuthCallback.tsx
+2
-2
Loading.tsx
web/src/pages/Loading.tsx
+0
-13
index.tsx
web/src/router/index.tsx
+17
-17
No files found.
web/src/components/MemoEditor/index.tsx
View file @
115d1bac
...
@@ -105,8 +105,6 @@ const MemoEditorImpl: React.FC<MemoEditorProps> = ({
...
@@ -105,8 +105,6 @@ const MemoEditorImpl: React.FC<MemoEditorProps> = ({
// Notify parent component of successful save
// Notify parent component of successful save
onConfirm
?.(
result
.
memoName
);
onConfirm
?.(
result
.
memoName
);
toast
.
success
(
"Saved successfully"
);
}
catch
(
error
)
{
}
catch
(
error
)
{
handleError
(
error
,
toast
.
error
,
{
handleError
(
error
,
toast
.
error
,
{
context
:
"Failed to save memo"
,
context
:
"Failed to save memo"
,
...
...
web/src/components/MemoSkeleton.tsx
deleted
100644 → 0
View file @
792d58b7
import
{
cn
}
from
"@/lib/utils"
;
interface
Props
{
showCreator
?:
boolean
;
count
?:
number
;
}
const
MemoSkeleton
=
({
showCreator
=
false
,
count
=
6
}:
Props
)
=>
{
return
(
<>
{
Array
.
from
({
length
:
count
}).
map
((
_
,
index
)
=>
(
<
div
key=
{
index
}
className=
"relative flex flex-col justify-start items-start bg-card w-full max-w-2xl mx-auto px-4 py-3 mb-2 gap-2 rounded-lg border border-border animate-pulse"
>
{
/* Header section */
}
<
div
className=
"w-full flex flex-row justify-between items-center gap-2"
>
<
div
className=
"w-auto max-w-[calc(100%-8rem)] grow flex flex-row justify-start items-center"
>
{
showCreator
?
(
<
div
className=
"w-full flex flex-row justify-start items-center gap-2"
>
{
/* Avatar skeleton */
}
<
div
className=
"w-8 h-8 rounded-full bg-muted shrink-0"
/>
<
div
className=
"w-full flex flex-col justify-center items-start gap-1"
>
{
/* Creator name skeleton */
}
<
div
className=
"h-4 w-24 bg-muted rounded"
/>
{
/* Timestamp skeleton */
}
<
div
className=
"h-3 w-16 bg-muted rounded"
/>
</
div
>
</
div
>
)
:
(
<
div
className=
"h-4 w-32 bg-muted rounded"
/>
)
}
</
div
>
{
/* Action buttons skeleton */
}
<
div
className=
"flex flex-row gap-2"
>
<
div
className=
"w-4 h-4 bg-muted rounded"
/>
<
div
className=
"w-4 h-4 bg-muted rounded"
/>
</
div
>
</
div
>
{
/* Content section */
}
<
div
className=
"w-full flex flex-col gap-2"
>
{
/* Text content skeleton - varied heights for realism */
}
<
div
className=
"space-y-2"
>
<
div
className=
{
cn
(
"h-4 bg-muted rounded"
,
index
%
3
===
0
?
"w-full"
:
index
%
3
===
1
?
"w-4/5"
:
"w-5/6"
)
}
/>
<
div
className=
{
cn
(
"h-4 bg-muted rounded"
,
index
%
2
===
0
?
"w-3/4"
:
"w-4/5"
)
}
/>
{
index
%
2
===
0
&&
<
div
className=
"h-4 w-2/3 bg-muted rounded"
/>
}
</
div
>
</
div
>
</
div
>
))
}
</>
);
};
export
default
MemoSkeleton
;
web/src/components/PagedMemoList/PagedMemoList.tsx
View file @
115d1bac
...
@@ -15,7 +15,7 @@ import type { MemoRenderContext } from "../MasonryView";
...
@@ -15,7 +15,7 @@ import type { MemoRenderContext } from "../MasonryView";
import
MasonryView
from
"../MasonryView"
;
import
MasonryView
from
"../MasonryView"
;
import
MemoEditor
from
"../MemoEditor"
;
import
MemoEditor
from
"../MemoEditor"
;
import
MemoFilters
from
"../MemoFilters"
;
import
MemoFilters
from
"../MemoFilters"
;
import
MemoSkeleton
from
"../Memo
Skeleton"
;
import
Skeleton
from
"../
Skeleton"
;
interface
Props
{
interface
Props
{
renderer
:
(
memo
:
Memo
,
context
?:
MemoRenderContext
)
=>
JSX
.
Element
;
renderer
:
(
memo
:
Memo
,
context
?:
MemoRenderContext
)
=>
JSX
.
Element
;
...
@@ -143,9 +143,7 @@ const PagedMemoList = (props: Props) => {
...
@@ -143,9 +143,7 @@ const PagedMemoList = (props: Props) => {
<
div
className=
"flex flex-col justify-start items-start w-full max-w-full"
>
<
div
className=
"flex flex-col justify-start items-start w-full max-w-full"
>
{
/* Show skeleton loader during initial load */
}
{
/* Show skeleton loader during initial load */
}
{
isLoading
?
(
{
isLoading
?
(
<
div
className=
"w-full flex flex-col justify-start items-center"
>
<
Skeleton
type=
"memo"
showCreator=
{
props
.
showCreator
}
count=
{
4
}
/>
<
MemoSkeleton
showCreator=
{
props
.
showCreator
}
count=
{
4
}
/>
</
div
>
)
:
(
)
:
(
<>
<>
<
MasonryView
<
MasonryView
...
@@ -162,12 +160,8 @@ const PagedMemoList = (props: Props) => {
...
@@ -162,12 +160,8 @@ const PagedMemoList = (props: Props) => {
listMode=
{
layout
===
"LIST"
}
listMode=
{
layout
===
"LIST"
}
/>
/>
{
/* Loading indicator for pagination */
}
{
/* Loading indicator for pagination - use skeleton for content consistency */
}
{
isFetchingNextPage
&&
(
{
isFetchingNextPage
&&
<
Skeleton
type=
"pagination"
showCreator=
{
props
.
showCreator
}
count=
{
2
}
/>
}
<
div
className=
"w-full flex flex-row justify-center items-center my-4"
>
<
LoaderIcon
className=
"animate-spin text-muted-foreground"
/>
</
div
>
)
}
{
/* Empty state or back-to-top button */
}
{
/* Empty state or back-to-top button */
}
{
!
isFetchingNextPage
&&
(
{
!
isFetchingNextPage
&&
(
...
...
web/src/components/Skeleton.tsx
0 → 100644
View file @
115d1bac
import
{
cn
}
from
"@/lib/utils"
;
interface
Props
{
type
?:
"route"
|
"memo"
|
"pagination"
;
showCreator
?:
boolean
;
count
?:
number
;
showEditor
?:
boolean
;
}
// Memo card skeleton component
const
MemoCardSkeleton
=
({
showCreator
=
false
,
index
=
0
}:
{
showCreator
?:
boolean
;
index
?:
number
})
=>
(
<
div
className=
"relative flex flex-col justify-start items-start bg-card w-full px-4 py-3 mb-2 gap-2 rounded-lg border border-border animate-pulse"
>
{
/* Header section */
}
<
div
className=
"w-full flex flex-row justify-between items-center gap-2"
>
<
div
className=
"w-auto max-w-[calc(100%-8rem)] grow flex flex-row justify-start items-center"
>
{
showCreator
?
(
<
div
className=
"w-full flex flex-row justify-start items-center gap-2"
>
<
div
className=
"w-8 h-8 rounded-full bg-muted shrink-0"
/>
<
div
className=
"w-full flex flex-col justify-center items-start gap-1"
>
<
div
className=
"h-4 w-24 bg-muted rounded"
/>
<
div
className=
"h-3 w-16 bg-muted rounded"
/>
</
div
>
</
div
>
)
:
(
<
div
className=
"h-4 w-32 bg-muted rounded"
/>
)
}
</
div
>
{
/* Action buttons skeleton */
}
<
div
className=
"flex flex-row gap-2"
>
<
div
className=
"w-4 h-4 bg-muted rounded"
/>
<
div
className=
"w-4 h-4 bg-muted rounded"
/>
</
div
>
</
div
>
{
/* Content section */
}
<
div
className=
"w-full flex flex-col gap-2"
>
<
div
className=
"space-y-2"
>
<
div
className=
{
cn
(
"h-4 bg-muted rounded"
,
index
%
3
===
0
?
"w-full"
:
index
%
3
===
1
?
"w-4/5"
:
"w-5/6"
)
}
/>
<
div
className=
{
cn
(
"h-4 bg-muted rounded"
,
index
%
2
===
0
?
"w-3/4"
:
"w-4/5"
)
}
/>
{
index
%
2
===
0
&&
<
div
className=
"h-4 w-2/3 bg-muted rounded"
/>
}
</
div
>
</
div
>
</
div
>
);
const
Skeleton
=
({
type
=
"route"
,
showCreator
=
false
,
count
=
4
,
showEditor
=
true
}:
Props
)
=>
{
// Pagination type: simpler, just memos
if
(
type
===
"pagination"
)
{
return
(
<
div
className=
"w-full flex flex-col justify-center items-center my-4"
>
<
div
className=
"w-full max-w-2xl mx-auto"
>
{
Array
.
from
({
length
:
count
}).
map
((
_
,
index
)
=>
(
<
MemoCardSkeleton
key=
{
index
}
showCreator=
{
showCreator
}
index=
{
index
}
/>
))
}
</
div
>
</
div
>
);
}
// Route or memo type: with optional wrapper
return
(
<
div
className=
"w-full max-w-full px-4 py-6"
>
<
div
className=
"w-full max-w-2xl mx-auto"
>
{
/* Editor skeleton - only for route type */
}
{
type
===
"route"
&&
showEditor
&&
(
<
div
className=
"relative flex flex-col justify-start items-start bg-card w-full px-4 py-3 mb-4 gap-2 rounded-lg border border-border animate-pulse"
>
<
div
className=
"w-full h-12 bg-muted rounded"
/>
</
div
>
)
}
{
/* Memo skeletons */
}
{
Array
.
from
({
length
:
count
}).
map
((
_
,
index
)
=>
(
<
MemoCardSkeleton
key=
{
index
}
showCreator=
{
showCreator
}
index=
{
index
}
/>
))
}
</
div
>
</
div
>
);
};
export
default
Skeleton
;
web/src/components/Spinner.tsx
0 → 100644
View file @
115d1bac
import
{
LoaderIcon
}
from
"lucide-react"
;
import
{
cn
}
from
"@/lib/utils"
;
interface
Props
{
className
?:
string
;
size
?:
"sm"
|
"md"
|
"lg"
;
}
const
Spinner
=
({
className
,
size
=
"md"
}:
Props
)
=>
{
const
sizeClasses
=
{
sm
:
"w-4 h-4"
,
md
:
"w-6 h-6"
,
lg
:
"w-8 h-8"
,
};
return
<
LoaderIcon
className=
{
cn
(
"animate-spin"
,
sizeClasses
[
size
],
className
)
}
/>;
};
export
default
Spinner
;
web/src/layouts/RootLayout.tsx
View file @
115d1bac
...
@@ -2,12 +2,12 @@ import { Suspense, useEffect, useMemo } from "react";
...
@@ -2,12 +2,12 @@ import { Suspense, useEffect, useMemo } from "react";
import
{
Outlet
,
useLocation
,
useSearchParams
}
from
"react-router-dom"
;
import
{
Outlet
,
useLocation
,
useSearchParams
}
from
"react-router-dom"
;
import
usePrevious
from
"react-use/lib/usePrevious"
;
import
usePrevious
from
"react-use/lib/usePrevious"
;
import
Navigation
from
"@/components/Navigation"
;
import
Navigation
from
"@/components/Navigation"
;
import
Skeleton
from
"@/components/Skeleton"
;
import
{
useInstance
}
from
"@/contexts/InstanceContext"
;
import
{
useInstance
}
from
"@/contexts/InstanceContext"
;
import
{
useMemoFilterContext
}
from
"@/contexts/MemoFilterContext"
;
import
{
useMemoFilterContext
}
from
"@/contexts/MemoFilterContext"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useMediaQuery
from
"@/hooks/useMediaQuery"
;
import
useMediaQuery
from
"@/hooks/useMediaQuery"
;
import
{
cn
}
from
"@/lib/utils"
;
import
{
cn
}
from
"@/lib/utils"
;
import
Loading
from
"@/pages/Loading"
;
import
{
redirectOnAuthFailure
}
from
"@/utils/auth-redirect"
;
import
{
redirectOnAuthFailure
}
from
"@/utils/auth-redirect"
;
const
RootLayout
=
()
=>
{
const
RootLayout
=
()
=>
{
...
@@ -47,7 +47,7 @@ const RootLayout = () => {
...
@@ -47,7 +47,7 @@ const RootLayout = () => {
</
div
>
</
div
>
)
}
)
}
<
main
className=
"w-full h-auto grow shrink flex flex-col justify-start items-center"
>
<
main
className=
"w-full h-auto grow shrink flex flex-col justify-start items-center"
>
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
/>
}
>
<
Outlet
/>
<
Outlet
/>
</
Suspense
>
</
Suspense
>
</
main
>
</
main
>
...
...
web/src/main.tsx
View file @
115d1bac
import
"@github/relative-time-element"
;
import
"@github/relative-time-element"
;
import
{
QueryClientProvider
}
from
"@tanstack/react-query"
;
import
{
QueryClientProvider
}
from
"@tanstack/react-query"
;
import
{
ReactQueryDevtools
}
from
"@tanstack/react-query-devtools"
;
import
{
ReactQueryDevtools
}
from
"@tanstack/react-query-devtools"
;
import
React
,
{
useEffect
,
use
State
}
from
"react"
;
import
React
,
{
useEffect
,
use
Ref
}
from
"react"
;
import
{
createRoot
}
from
"react-dom/client"
;
import
{
createRoot
}
from
"react-dom/client"
;
import
{
Toaster
}
from
"react-hot-toast"
;
import
{
Toaster
}
from
"react-hot-toast"
;
import
{
RouterProvider
}
from
"react-router-dom"
;
import
{
RouterProvider
}
from
"react-router-dom"
;
...
@@ -12,7 +12,6 @@ import { AuthProvider, useAuth } from "@/contexts/AuthContext";
...
@@ -12,7 +12,6 @@ import { AuthProvider, useAuth } from "@/contexts/AuthContext";
import
{
InstanceProvider
,
useInstance
}
from
"@/contexts/InstanceContext"
;
import
{
InstanceProvider
,
useInstance
}
from
"@/contexts/InstanceContext"
;
import
{
ViewProvider
}
from
"@/contexts/ViewContext"
;
import
{
ViewProvider
}
from
"@/contexts/ViewContext"
;
import
{
queryClient
}
from
"@/lib/query-client"
;
import
{
queryClient
}
from
"@/lib/query-client"
;
import
Loading
from
"@/pages/Loading"
;
import
router
from
"./router"
;
import
router
from
"./router"
;
import
{
applyLocaleEarly
}
from
"./utils/i18n"
;
import
{
applyLocaleEarly
}
from
"./utils/i18n"
;
import
{
applyThemeEarly
}
from
"./utils/theme"
;
import
{
applyThemeEarly
}
from
"./utils/theme"
;
...
@@ -26,22 +25,21 @@ applyLocaleEarly();
...
@@ -26,22 +25,21 @@ applyLocaleEarly();
function
AppInitializer
({
children
}:
{
children
:
React
.
ReactNode
})
{
function
AppInitializer
({
children
}:
{
children
:
React
.
ReactNode
})
{
const
{
isInitialized
:
authInitialized
,
initialize
:
initAuth
}
=
useAuth
();
const
{
isInitialized
:
authInitialized
,
initialize
:
initAuth
}
=
useAuth
();
const
{
isInitialized
:
instanceInitialized
,
initialize
:
initInstance
}
=
useInstance
();
const
{
isInitialized
:
instanceInitialized
,
initialize
:
initInstance
}
=
useInstance
();
const
[
initStarted
,
setInitStarted
]
=
useState
(
false
);
const
initStartedRef
=
useRef
(
false
);
// Initialize on mount
// Initialize on mount
- run in parallel for better performance
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
initStarted
)
return
;
if
(
initStarted
Ref
.
current
)
return
;
setInitStarted
(
true
)
;
initStartedRef
.
current
=
true
;
const
init
=
async
()
=>
{
const
init
=
async
()
=>
{
await
initInstance
();
await
Promise
.
all
([
initInstance
(),
initAuth
()]);
await
initAuth
();
};
};
init
();
init
();
},
[
initAuth
,
initInstance
,
initStarted
]);
},
[
initAuth
,
initInstance
]);
if
(
!
authInitialized
||
!
instanceInitialized
)
{
if
(
!
authInitialized
||
!
instanceInitialized
)
{
return
<
Loading
/>
;
return
undefined
;
}
}
return
<>
{
children
}
</>;
return
<>
{
children
}
</>;
...
...
web/src/pages/AuthCallback.tsx
View file @
115d1bac
import
{
timestampDate
}
from
"@bufbuild/protobuf/wkt"
;
import
{
timestampDate
}
from
"@bufbuild/protobuf/wkt"
;
import
{
LoaderIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useSearchParams
}
from
"react-router-dom"
;
import
{
useSearchParams
}
from
"react-router-dom"
;
import
{
setAccessToken
}
from
"@/auth-state"
;
import
{
setAccessToken
}
from
"@/auth-state"
;
import
Spinner
from
"@/components/Spinner"
;
import
{
authServiceClient
}
from
"@/connect"
;
import
{
authServiceClient
}
from
"@/connect"
;
import
{
useAuth
}
from
"@/contexts/AuthContext"
;
import
{
useAuth
}
from
"@/contexts/AuthContext"
;
import
{
absolutifyLink
}
from
"@/helpers/utils"
;
import
{
absolutifyLink
}
from
"@/helpers/utils"
;
...
@@ -113,7 +113,7 @@ const AuthCallback = () => {
...
@@ -113,7 +113,7 @@ const AuthCallback = () => {
return
(
return
(
<
div
className=
"p-4 py-24 w-full h-full flex justify-center items-center"
>
<
div
className=
"p-4 py-24 w-full h-full flex justify-center items-center"
>
{
state
.
loading
?
(
{
state
.
loading
?
(
<
LoaderIcon
className=
"animate-spin text-foreground
"
/>
<
Spinner
size=
"lg
"
/>
)
:
(
)
:
(
<
div
className=
"max-w-lg font-mono whitespace-pre-wrap opacity-80"
>
{
state
.
errorMessage
}
</
div
>
<
div
className=
"max-w-lg font-mono whitespace-pre-wrap opacity-80"
>
{
state
.
errorMessage
}
</
div
>
)
}
)
}
...
...
web/src/pages/Loading.tsx
deleted
100644 → 0
View file @
792d58b7
import
{
LoaderIcon
}
from
"lucide-react"
;
function
Loading
()
{
return
(
<
div
className=
"fixed w-full h-full flex flex-row justify-center items-center"
>
<
div
className=
"w-80 max-w-full h-full py-4 flex flex-col justify-center items-center"
>
<
LoaderIcon
className=
"animate-spin text-foreground"
/>
</
div
>
</
div
>
);
}
export
default
Loading
;
web/src/router/index.tsx
View file @
115d1bac
import
{
lazy
,
Suspense
}
from
"react"
;
import
{
lazy
,
Suspense
}
from
"react"
;
import
{
createBrowserRouter
}
from
"react-router-dom"
;
import
{
createBrowserRouter
}
from
"react-router-dom"
;
import
App
from
"@/App"
;
import
App
from
"@/App"
;
import
Skeleton
from
"@/components/Skeleton"
;
import
MainLayout
from
"@/layouts/MainLayout"
;
import
MainLayout
from
"@/layouts/MainLayout"
;
import
RootLayout
from
"@/layouts/RootLayout"
;
import
RootLayout
from
"@/layouts/RootLayout"
;
import
Home
from
"@/pages/Home"
;
import
Home
from
"@/pages/Home"
;
import
Loading
from
"@/pages/Loading"
;
const
AdminSignIn
=
lazy
(()
=>
import
(
"@/pages/AdminSignIn"
));
const
AdminSignIn
=
lazy
(()
=>
import
(
"@/pages/AdminSignIn"
));
const
Archived
=
lazy
(()
=>
import
(
"@/pages/Archived"
));
const
Archived
=
lazy
(()
=>
import
(
"@/pages/Archived"
));
...
@@ -39,7 +39,7 @@ const router = createBrowserRouter([
...
@@ -39,7 +39,7 @@ const router = createBrowserRouter([
{
{
path
:
""
,
path
:
""
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
SignIn
/>
<
SignIn
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -47,7 +47,7 @@ const router = createBrowserRouter([
...
@@ -47,7 +47,7 @@ const router = createBrowserRouter([
{
{
path
:
"admin"
,
path
:
"admin"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
AdminSignIn
/>
<
AdminSignIn
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -55,7 +55,7 @@ const router = createBrowserRouter([
...
@@ -55,7 +55,7 @@ const router = createBrowserRouter([
{
{
path
:
"signup"
,
path
:
"signup"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
SignUp
/>
<
SignUp
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -63,7 +63,7 @@ const router = createBrowserRouter([
...
@@ -63,7 +63,7 @@ const router = createBrowserRouter([
{
{
path
:
"callback"
,
path
:
"callback"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
AuthCallback
/>
<
AuthCallback
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -84,7 +84,7 @@ const router = createBrowserRouter([
...
@@ -84,7 +84,7 @@ const router = createBrowserRouter([
{
{
path
:
Routes
.
EXPLORE
,
path
:
Routes
.
EXPLORE
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
Explore
/>
<
Explore
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -92,7 +92,7 @@ const router = createBrowserRouter([
...
@@ -92,7 +92,7 @@ const router = createBrowserRouter([
{
{
path
:
Routes
.
ARCHIVED
,
path
:
Routes
.
ARCHIVED
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
Archived
/>
<
Archived
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -100,7 +100,7 @@ const router = createBrowserRouter([
...
@@ -100,7 +100,7 @@ const router = createBrowserRouter([
{
{
path
:
"u/:username"
,
path
:
"u/:username"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
UserProfile
/>
<
UserProfile
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -110,7 +110,7 @@ const router = createBrowserRouter([
...
@@ -110,7 +110,7 @@ const router = createBrowserRouter([
{
{
path
:
Routes
.
ATTACHMENTS
,
path
:
Routes
.
ATTACHMENTS
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
Attachments
/>
<
Attachments
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -118,7 +118,7 @@ const router = createBrowserRouter([
...
@@ -118,7 +118,7 @@ const router = createBrowserRouter([
{
{
path
:
Routes
.
CALENDAR
,
path
:
Routes
.
CALENDAR
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
Calendar
/>
<
Calendar
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -126,7 +126,7 @@ const router = createBrowserRouter([
...
@@ -126,7 +126,7 @@ const router = createBrowserRouter([
{
{
path
:
Routes
.
INBOX
,
path
:
Routes
.
INBOX
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
Inboxes
/>
<
Inboxes
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -134,7 +134,7 @@ const router = createBrowserRouter([
...
@@ -134,7 +134,7 @@ const router = createBrowserRouter([
{
{
path
:
Routes
.
SETTING
,
path
:
Routes
.
SETTING
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
Setting
/>
<
Setting
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -142,7 +142,7 @@ const router = createBrowserRouter([
...
@@ -142,7 +142,7 @@ const router = createBrowserRouter([
{
{
path
:
"memos/:uid"
,
path
:
"memos/:uid"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
MemoDetail
/>
<
MemoDetail
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -151,7 +151,7 @@ const router = createBrowserRouter([
...
@@ -151,7 +151,7 @@ const router = createBrowserRouter([
{
{
path
:
"m/:uid"
,
path
:
"m/:uid"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
MemoDetailRedirect
/>
<
MemoDetailRedirect
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -159,7 +159,7 @@ const router = createBrowserRouter([
...
@@ -159,7 +159,7 @@ const router = createBrowserRouter([
{
{
path
:
"403"
,
path
:
"403"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
PermissionDenied
/>
<
PermissionDenied
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -167,7 +167,7 @@ const router = createBrowserRouter([
...
@@ -167,7 +167,7 @@ const router = createBrowserRouter([
{
{
path
:
"404"
,
path
:
"404"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
NotFound
/>
<
NotFound
/>
</
Suspense
>
</
Suspense
>
),
),
...
@@ -175,7 +175,7 @@ const router = createBrowserRouter([
...
@@ -175,7 +175,7 @@ const router = createBrowserRouter([
{
{
path
:
"*"
,
path
:
"*"
,
element
:
(
element
:
(
<
Suspense
fallback=
{
<
Loading
/>
}
>
<
Suspense
fallback=
{
<
Skeleton
type=
"route"
showEditor=
{
false
}
/>
}
>
<
NotFound
/>
<
NotFound
/>
</
Suspense
>
</
Suspense
>
),
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment