refactor: move bookmarks entry location

This commit is contained in:
codytseng
2025-10-19 15:46:45 +08:00
parent a847c4dc56
commit 5c2a016d4b
13 changed files with 95 additions and 69 deletions

View File

@@ -20,6 +20,7 @@ import BottomNavigationBar from './components/BottomNavigationBar'
import CreateWalletGuideToast from './components/CreateWalletGuideToast'
import TooManyRelaysAlertDialog from './components/TooManyRelaysAlertDialog'
import { normalizeUrl } from './lib/url'
import BookmarkPage from './pages/primary/BookmarkPage'
import ExplorePage from './pages/primary/ExplorePage'
import MePage from './pages/primary/MePage'
import NotificationListPage from './pages/primary/NotificationListPage'
@@ -61,7 +62,8 @@ const PRIMARY_PAGE_REF_MAP = {
me: createRef<TPageRef>(),
profile: createRef<TPageRef>(),
relay: createRef<TPageRef>(),
search: createRef<TPageRef>()
search: createRef<TPageRef>(),
bookmark: createRef<TPageRef>()
}
const PRIMARY_PAGE_MAP = {
@@ -71,7 +73,8 @@ const PRIMARY_PAGE_MAP = {
me: <MePage ref={PRIMARY_PAGE_REF_MAP.me} />,
profile: <ProfilePage ref={PRIMARY_PAGE_REF_MAP.profile} />,
relay: <RelayPage ref={PRIMARY_PAGE_REF_MAP.relay} />,
search: <SearchPage ref={PRIMARY_PAGE_REF_MAP.search} />
search: <SearchPage ref={PRIMARY_PAGE_REF_MAP.search} />,
bookmark: <BookmarkPage ref={PRIMARY_PAGE_REF_MAP.bookmark} />
}
const PrimaryPageContext = createContext<TPrimaryPageContext | undefined>(undefined)

View File

@@ -4,7 +4,7 @@ import { SecondaryPageLink } from '@/PageManager'
import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
import { useFeed } from '@/providers/FeedProvider'
import { useNostr } from '@/providers/NostrProvider'
import { BookmarkIcon, UsersRound } from 'lucide-react'
import { UsersRound } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import RelayIcon from '../RelayIcon'
import RelaySetCard from '../RelaySetCard'
@@ -35,24 +35,6 @@ export default function FeedSwitcher({ close }: { close?: () => void }) {
</FeedSwitcherItem>
)}
{pubkey && (
<FeedSwitcherItem
isActive={feedInfo.feedType === 'bookmarks'}
onClick={() => {
if (!pubkey) return
switchFeed('bookmarks', { pubkey })
close?.()
}}
>
<div className="flex gap-2 items-center">
<div className="flex justify-center items-center w-6 h-6 shrink-0">
<BookmarkIcon className="size-4" />
</div>
<div>{t('Bookmarks')}</div>
</div>
</FeedSwitcherItem>
)}
<div className="flex justify-end items-center text-sm">
<SecondaryPageLink
to={toRelaySettings()}

View File

@@ -0,0 +1,20 @@
import { usePrimaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider'
import { Bookmark } from 'lucide-react'
import SidebarItem from './SidebarItem'
export default function BookmarkButton({ collapse }: { collapse: boolean }) {
const { navigate, current } = usePrimaryPage()
const { checkLogin } = useNostr()
return (
<SidebarItem
title="Bookmarks"
onClick={() => checkLogin(() => navigate('bookmark'))}
active={current === 'bookmark'}
collapse={collapse}
>
<Bookmark />
</SidebarItem>
)
}

View File

@@ -1,11 +1,13 @@
import Icon from '@/assets/Icon'
import Logo from '@/assets/Logo'
import { cn } from '@/lib/utils'
import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { useTheme } from '@/providers/ThemeProvider'
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
import { ChevronsLeft, ChevronsRight } from 'lucide-react'
import AccountButton from './AccountButton'
import BookmarkButton from './BookmarkButton'
import RelaysButton from './ExploreButton'
import HomeButton from './HomeButton'
import NotificationsButton from './NotificationButton'
@@ -18,6 +20,7 @@ export default function PrimaryPageSidebar() {
const { isSmallScreen } = useScreenSize()
const { themeSetting } = useTheme()
const { sidebarCollapse, updateSidebarCollapse, enableSingleColumnLayout } = useUserPreferences()
const { pubkey } = useNostr()
if (isSmallScreen) return null
@@ -43,6 +46,7 @@ export default function PrimaryPageSidebar() {
<NotificationsButton collapse={sidebarCollapse && !enableSingleColumnLayout} />
<SearchButton collapse={sidebarCollapse && !enableSingleColumnLayout} />
<ProfileButton collapse={sidebarCollapse && !enableSingleColumnLayout} />
{pubkey && <BookmarkButton collapse={sidebarCollapse && !enableSingleColumnLayout} />}
<SettingsButton collapse={sidebarCollapse && !enableSingleColumnLayout} />
<PostButton collapse={sidebarCollapse && !enableSingleColumnLayout} />
</div>

View File

@@ -1,6 +1,6 @@
import { TSearchParams } from '@/types'
import { Event, nip19 } from 'nostr-tools'
import { getNoteBech32Id } from './event'
import { TSearchParams } from '@/types'
export const toHome = () => '/'
export const toNote = (eventOrId: Event | string) => {
@@ -76,6 +76,7 @@ export const toRelay = (url: string) => `/relays/${encodeURIComponent(url)}`
export const toRelayReviews = (url: string) => `/relays/${encodeURIComponent(url)}/reviews`
export const toMuteList = () => '/mutes'
export const toRizful = () => '/rizful'
export const toBookmarks = () => '/bookmarks'
export const toChachiChat = (relay: string, d: string) => {
return `https://chachi.chat/${relay.replace(/^wss?:\/\//, '').replace(/\/$/, '')}/${d}`

View File

@@ -0,0 +1,35 @@
import BookmarkList from '@/components/BookmarkList'
import PrimaryPageLayout from '@/layouts/PrimaryPageLayout'
import { TPageRef } from '@/types'
import { BookmarkIcon } from 'lucide-react'
import { forwardRef, useImperativeHandle, useRef } from 'react'
import { useTranslation } from 'react-i18next'
const BookmarkPage = forwardRef((_, ref) => {
const layoutRef = useRef<TPageRef>(null)
useImperativeHandle(ref, () => layoutRef.current)
return (
<PrimaryPageLayout
pageName="bookmark"
ref={layoutRef}
titlebar={<BookmarkPageTitlebar />}
displayScrollToTopButton
>
<BookmarkList />
</PrimaryPageLayout>
)
})
BookmarkPage.displayName = 'BookmarkPage'
export default BookmarkPage
function BookmarkPageTitlebar() {
const { t } = useTranslation()
return (
<div className="flex gap-2 items-center h-full pl-3">
<BookmarkIcon />
<div className="text-lg font-semibold">{t('Bookmarks')}</div>
</div>
)
}

View File

@@ -1,19 +1,20 @@
import AccountManager from '@/components/AccountManager'
import LoginDialog from '@/components/LoginDialog'
import LogoutDialog from '@/components/LogoutDialog'
import PubkeyCopy from '@/components/PubkeyCopy'
import NpubQrCode from '@/components/NpubQrCode'
import PubkeyCopy from '@/components/PubkeyCopy'
import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator'
import { SimpleUserAvatar } from '@/components/UserAvatar'
import { SimpleUsername } from '@/components/Username'
import PrimaryPageLayout from '@/layouts/PrimaryPageLayout'
import { toProfile, toRelaySettings, toSettings, toWallet } from '@/lib/link'
import { toBookmarks, toProfile, toRelaySettings, toSettings, toWallet } from '@/lib/link'
import { cn } from '@/lib/utils'
import { useSecondaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider'
import {
ArrowDownUp,
Bookmark,
ChevronRight,
LogOut,
Server,
@@ -75,6 +76,9 @@ const MePage = forwardRef((_, ref) => {
<Item onClick={() => push(toRelaySettings())}>
<Server /> {t('Relays')}
</Item>
<Item onClick={() => push(toBookmarks())}>
<Bookmark /> {t('Bookmarks')}
</Item>
<Item onClick={() => push(toWallet())}>
<Wallet />
{t('Wallet')}

View File

@@ -6,7 +6,7 @@ import { cn } from '@/lib/utils'
import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
import { useFeed } from '@/providers/FeedProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { BookmarkIcon, ChevronDown, Server, UsersRound } from 'lucide-react'
import { ChevronDown, Server, UsersRound } from 'lucide-react'
import { forwardRef, HTMLAttributes, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
@@ -62,9 +62,6 @@ const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEle
if (feedInfo.feedType === 'following') {
return t('Following')
}
if (feedInfo.feedType === 'bookmarks') {
return t('Bookmarks')
}
if (relayUrls.length === 0) {
return t('Choose a relay')
}
@@ -82,13 +79,7 @@ const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEle
ref={ref}
{...props}
>
{feedInfo.feedType === 'following' ? (
<UsersRound />
) : feedInfo.feedType === 'bookmarks' ? (
<BookmarkIcon />
) : (
<Server />
)}
{feedInfo.feedType === 'following' ? <UsersRound /> : <Server />}
<div className="text-lg font-semibold truncate">{title}</div>
<ChevronDown />
</div>

View File

@@ -1,5 +1,4 @@
import { useSecondaryPage } from '@/PageManager'
import BookmarkList from '@/components/BookmarkList'
import PostEditor from '@/components/PostEditor'
import RelayInfo from '@/components/RelayInfo'
import { Button } from '@/components/ui/button'
@@ -60,18 +59,6 @@ const NoteListPage = forwardRef((_, ref) => {
</Button>
</div>
)
} else if (feedInfo.feedType === 'bookmarks') {
if (!pubkey) {
content = (
<div className="flex justify-center w-full">
<Button size="lg" onClick={() => checkLogin()}>
{t('Please login to view bookmarks')}
</Button>
</div>
)
} else {
content = <BookmarkList />
}
} else if (feedInfo.feedType === 'following') {
content = <FollowingFeed />
} else {

View File

@@ -0,0 +1,16 @@
import BookmarkList from '@/components/BookmarkList'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { forwardRef } from 'react'
import { useTranslation } from 'react-i18next'
const BookmarkPage = forwardRef(({ index }: { index?: number }, ref) => {
const { t } = useTranslation()
return (
<SecondaryPageLayout index={index} title={t('Bookmarks')} displayScrollToTopButton ref={ref}>
<BookmarkList />
</SecondaryPageLayout>
)
})
BookmarkPage.displayName = 'BookmarkPage'
export default BookmarkPage

View File

@@ -69,10 +69,6 @@ export function FeedProvider({ children }: { children: React.ReactNode }) {
if (feedInfo.feedType === 'following' && pubkey) {
return await switchFeed('following', { pubkey })
}
if (feedInfo.feedType === 'bookmarks' && pubkey) {
return await switchFeed('bookmarks', { pubkey })
}
}
init()
@@ -147,21 +143,6 @@ export function FeedProvider({ children }: { children: React.ReactNode }) {
setIsReady(true)
return
}
if (feedType === 'bookmarks') {
if (!options.pubkey) {
setIsReady(true)
return
}
const newFeedInfo = { feedType }
setFeedInfo(newFeedInfo)
feedInfoRef.current = newFeedInfo
storage.setFeedInfo(newFeedInfo, pubkey)
setRelayUrls([])
setIsReady(true)
return
}
setIsReady(true)
}

View File

@@ -1,6 +1,7 @@
import { match } from 'path-to-regexp'
import { isValidElement } from 'react'
import AppearanceSettingsPage from './pages/secondary/AppearanceSettingsPage'
import BookmarkPage from './pages/secondary/BookmarkPage'
import FollowingListPage from './pages/secondary/FollowingListPage'
import GeneralSettingsPage from './pages/secondary/GeneralSettingsPage'
import MuteListPage from './pages/secondary/MuteListPage'
@@ -39,7 +40,8 @@ const ROUTES = [
{ path: '/settings/translation', element: <TranslationPage /> },
{ path: '/profile-editor', element: <ProfileEditorPage /> },
{ path: '/mutes', element: <MuteListPage /> },
{ path: '/rizful', element: <RizfulPage /> }
{ path: '/rizful', element: <RizfulPage /> },
{ path: '/bookmarks', element: <BookmarkPage /> }
]
export const routes = ROUTES.map(({ path, element }) => ({

View File

@@ -106,7 +106,7 @@ export type TAccount = {
export type TAccountPointer = Pick<TAccount, 'pubkey' | 'signerType'>
export type TFeedType = 'following' | 'relays' | 'relay' | 'bookmarks'
export type TFeedType = 'following' | 'relays' | 'relay'
export type TFeedInfo = { feedType: TFeedType; id?: string }
export type TLanguage = 'en' | 'zh' | 'pl'