feat: community mode (#738)
Co-authored-by: CXPLAY <62034099+cxplay@users.noreply.github.com>
This commit is contained in:
parent
686b1f9998
commit
ed8a22d5bc
21 changed files with 303 additions and 101 deletions
16
src/components/BottomNavigationBar/FollowingButton.tsx
Normal file
16
src/components/BottomNavigationBar/FollowingButton.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { usePrimaryPage } from '@/PageManager'
|
||||
import { UsersRound } from 'lucide-react'
|
||||
import BottomNavigationBarItem from './BottomNavigationBarItem'
|
||||
|
||||
export default function FollowingButton() {
|
||||
const { navigate, current, display } = usePrimaryPage()
|
||||
|
||||
return (
|
||||
<BottomNavigationBarItem
|
||||
active={current === 'following' && display}
|
||||
onClick={() => navigate('following')}
|
||||
>
|
||||
<UsersRound />
|
||||
</BottomNavigationBarItem>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
import { IS_COMMUNITY_MODE } from '@/constants'
|
||||
import { cn } from '@/lib/utils'
|
||||
import BackgroundAudio from '../BackgroundAudio'
|
||||
import AccountButton from './AccountButton'
|
||||
import ExploreButton from './ExploreButton'
|
||||
import FollowingButton from './FollowingButton'
|
||||
import HomeButton from './HomeButton'
|
||||
import NotificationsButton from './NotificationsButton'
|
||||
|
||||
|
|
@ -16,7 +18,8 @@ export default function BottomNavigationBar() {
|
|||
<BackgroundAudio className="rounded-none border-x-0 border-b border-t-0 bg-background" />
|
||||
<div className="flex w-full items-center justify-around [&_svg]:size-4 [&_svg]:shrink-0">
|
||||
<HomeButton />
|
||||
<ExploreButton />
|
||||
{!IS_COMMUNITY_MODE && <ExploreButton />}
|
||||
{IS_COMMUNITY_MODE && <FollowingButton />}
|
||||
<NotificationsButton />
|
||||
<AccountButton />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { IS_COMMUNITY_MODE } from '@/constants'
|
||||
import { toRelay } from '@/lib/link'
|
||||
import { useSecondaryPage } from '@/PageManager'
|
||||
import { useSortable } from '@dnd-kit/sortable'
|
||||
|
|
@ -38,7 +39,7 @@ export default function RelayItem({ relay }: { relay: string }) {
|
|||
<div className="w-0 flex-1 truncate font-semibold">{relay}</div>
|
||||
</div>
|
||||
</div>
|
||||
<SaveRelayDropdownMenu urls={[relay]} />
|
||||
{!IS_COMMUNITY_MODE && <SaveRelayDropdownMenu urls={[relay]} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { IS_COMMUNITY_MODE, COMMUNITY_RELAY_SETS, COMMUNITY_RELAYS } from '@/constants'
|
||||
import { toRelaySettings } from '@/lib/link'
|
||||
import { simplifyUrl } from '@/lib/url'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
|
@ -18,12 +19,45 @@ export default function FeedSwitcher({ close }: { close?: () => void }) {
|
|||
const { relaySets, favoriteRelays } = useFavoriteRelays()
|
||||
const { feedInfo, switchFeed } = useFeed()
|
||||
const { pinnedPubkeySet } = usePinnedUsers()
|
||||
const filteredRelaySets = useMemo(
|
||||
() => relaySets.filter((set) => set.relayUrls.length > 0),
|
||||
[relaySets]
|
||||
)
|
||||
const filteredRelaySets = useMemo(() => {
|
||||
return relaySets.filter((set) => set.relayUrls.length > 0)
|
||||
}, [relaySets])
|
||||
const hasRelays = filteredRelaySets.length > 0 || favoriteRelays.length > 0
|
||||
|
||||
if (IS_COMMUNITY_MODE) {
|
||||
return (
|
||||
<div className="space-y-1.5">
|
||||
{COMMUNITY_RELAY_SETS.map((set) => (
|
||||
<RelaySetCard
|
||||
key={set.id}
|
||||
relaySet={set}
|
||||
select={feedInfo?.feedType === 'relays' && set.id === feedInfo.id}
|
||||
onSelectChange={(select) => {
|
||||
if (!select) return
|
||||
switchFeed('relays', { activeRelaySetId: set.id })
|
||||
close?.()
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{COMMUNITY_RELAYS.map((relay) => (
|
||||
<FeedSwitcherItem
|
||||
key={relay}
|
||||
isActive={feedInfo?.feedType === 'relay' && feedInfo.id === relay}
|
||||
onClick={() => {
|
||||
switchFeed('relay', { relay })
|
||||
close?.()
|
||||
}}
|
||||
>
|
||||
<div className="flex w-full items-center gap-3">
|
||||
<RelayIcon url={relay} className="shrink-0" />
|
||||
<div className="w-0 flex-1 truncate">{simplifyUrl(relay)}</div>
|
||||
</div>
|
||||
</FeedSwitcherItem>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* Personal Feeds Section */}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area'
|
||||
import { IS_COMMUNITY_MODE } from '@/constants'
|
||||
import { useFetchRelayInfo } from '@/hooks'
|
||||
import { createFakeEvent } from '@/lib/event'
|
||||
import { checkNip43Support } from '@/lib/relay'
|
||||
import { normalizeHttpUrl } from '@/lib/url'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
|
@ -10,6 +12,7 @@ import { Check, Copy, GitBranch, Mail, Share2, SquareCode } from 'lucide-react'
|
|||
import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { toast } from 'sonner'
|
||||
import Content from '../Content'
|
||||
import PostEditor from '../PostEditor'
|
||||
import RelayIcon from '../RelayIcon'
|
||||
import RelayMembershipControl from '../RelayMembershipControl'
|
||||
|
|
@ -17,8 +20,6 @@ import SaveRelayDropdownMenu from '../SaveRelayDropdownMenu'
|
|||
import UserAvatar from '../UserAvatar'
|
||||
import Username from '../Username'
|
||||
import RelayReviewsPreview from './RelayReviewsPreview'
|
||||
import Content from '../Content'
|
||||
import { createFakeEvent } from '@/lib/event'
|
||||
|
||||
export default function RelayInfo({ url, className }: { url: string; className?: string }) {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -161,7 +162,7 @@ function RelayControls({ url }: { url: string }) {
|
|||
<Button variant="ghost" size="titlebar-icon" onClick={handleCopyUrl}>
|
||||
{copiedUrl ? <Check /> : <Copy />}
|
||||
</Button>
|
||||
<SaveRelayDropdownMenu urls={[url]} bigButton />
|
||||
{!IS_COMMUNITY_MODE && <SaveRelayDropdownMenu urls={[url]} bigButton />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { IS_COMMUNITY_MODE } from '@/constants'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { TRelayInfo } from '@/types'
|
||||
import { HTMLProps } from 'react'
|
||||
|
|
@ -30,7 +31,7 @@ export default function RelaySimpleInfo({
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{relayInfo && <SaveRelayDropdownMenu urls={[relayInfo.url]} />}
|
||||
{relayInfo && !IS_COMMUNITY_MODE && <SaveRelayDropdownMenu urls={[relayInfo.url]} />}
|
||||
</div>
|
||||
{!!relayInfo?.description && (
|
||||
<div
|
||||
|
|
|
|||
20
src/components/Sidebar/FollowingButton.tsx
Normal file
20
src/components/Sidebar/FollowingButton.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { usePrimaryPage } from '@/PageManager'
|
||||
import { Users2 } from 'lucide-react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function FollowingButton({ collapse }: { collapse: boolean }) {
|
||||
const { t } = useTranslation()
|
||||
const { navigate, current, display } = usePrimaryPage()
|
||||
|
||||
return (
|
||||
<SidebarItem
|
||||
title={t('Following')}
|
||||
onClick={() => navigate('following')}
|
||||
active={display && current === 'following'}
|
||||
collapse={collapse}
|
||||
>
|
||||
<Users2 />
|
||||
</SidebarItem>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import Icon from '@/assets/Icon'
|
||||
import Logo from '@/assets/Logo'
|
||||
import { IS_COMMUNITY_MODE } from '@/constants'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { usePrimaryPage } from '@/PageManager'
|
||||
import { useNostr } from '@/providers/NostrProvider'
|
||||
|
|
@ -10,6 +11,7 @@ import { ChevronsLeft, ChevronsRight } from 'lucide-react'
|
|||
import AccountButton from './AccountButton'
|
||||
import BookmarkButton from './BookmarkButton'
|
||||
import RelaysButton from './ExploreButton'
|
||||
import FollowingButton from './FollowingButton'
|
||||
import HomeButton from './HomeButton'
|
||||
import LayoutSwitcher from './LayoutSwitcher'
|
||||
import NotificationsButton from './NotificationButton'
|
||||
|
|
@ -53,7 +55,8 @@ export default function PrimaryPageSidebar() {
|
|||
</button>
|
||||
)}
|
||||
<HomeButton collapse={sidebarCollapse} />
|
||||
<RelaysButton collapse={sidebarCollapse} />
|
||||
{!IS_COMMUNITY_MODE && <RelaysButton collapse={sidebarCollapse} />}
|
||||
{IS_COMMUNITY_MODE && <FollowingButton collapse={sidebarCollapse} />}
|
||||
<NotificationsButton collapse={sidebarCollapse} />
|
||||
<SearchButton collapse={sidebarCollapse} />
|
||||
<ProfileButton collapse={sidebarCollapse} />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { kinds } from 'nostr-tools'
|
||||
import { TRelaySet } from './types'
|
||||
|
||||
export const JUMBLE_API_BASE_URL = 'https://api.jumble.social'
|
||||
|
||||
|
|
@ -483,3 +484,8 @@ export const SPECIAL_TRUST_SCORE_FILTER_ID = {
|
|||
NAK: 'nak',
|
||||
TRENDING: 'trending'
|
||||
}
|
||||
|
||||
export const COMMUNITY_RELAY_SETS = import.meta.env.VITE_COMMUNITY_RELAY_SETS as TRelaySet[]
|
||||
export const COMMUNITY_RELAYS = import.meta.env.VITE_COMMUNITY_RELAYS as string[]
|
||||
|
||||
export const IS_COMMUNITY_MODE = COMMUNITY_RELAY_SETS.length > 0 || COMMUNITY_RELAYS.length > 0
|
||||
|
|
|
|||
32
src/pages/primary/FollowingPage/index.tsx
Normal file
32
src/pages/primary/FollowingPage/index.tsx
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import FollowingFeed from '@/components/FollowingFeed'
|
||||
import PrimaryPageLayout from '@/layouts/PrimaryPageLayout'
|
||||
import { TPageRef } from '@/types'
|
||||
import { UsersRound } from 'lucide-react'
|
||||
import { forwardRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const FollowingPage = forwardRef<TPageRef>((_, ref) => {
|
||||
return (
|
||||
<PrimaryPageLayout
|
||||
pageName="following"
|
||||
titlebar={<FollowingPageTitlebar />}
|
||||
displayScrollToTopButton
|
||||
ref={ref}
|
||||
>
|
||||
<FollowingFeed />
|
||||
</PrimaryPageLayout>
|
||||
)
|
||||
})
|
||||
FollowingPage.displayName = 'FollowingPage'
|
||||
export default FollowingPage
|
||||
|
||||
function FollowingPageTitlebar() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="flex h-full items-center gap-2 pl-3">
|
||||
<UsersRound />
|
||||
<div className="text-lg font-semibold">{t('Following')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ import FeedSwitcher from '@/components/FeedSwitcher'
|
|||
import RelayIcon from '@/components/RelayIcon'
|
||||
import { Drawer, DrawerContent } from '@/components/ui/drawer'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import { IS_COMMUNITY_MODE, COMMUNITY_RELAY_SETS, COMMUNITY_RELAYS } from '@/constants'
|
||||
import { simplifyUrl } from '@/lib/url'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider'
|
||||
|
|
@ -15,6 +16,10 @@ export default function FeedButton({ className }: { className?: string }) {
|
|||
const { isSmallScreen } = useScreenSize()
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
if (IS_COMMUNITY_MODE && COMMUNITY_RELAY_SETS.length + COMMUNITY_RELAYS.length <= 1) {
|
||||
return <FeedSwitcherTrigger className={className} />
|
||||
}
|
||||
|
||||
if (isSmallScreen) {
|
||||
return (
|
||||
<>
|
||||
|
|
@ -61,7 +66,8 @@ const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEle
|
|||
const { relaySets } = useFavoriteRelays()
|
||||
const activeRelaySet = useMemo(() => {
|
||||
return feedInfo?.feedType === 'relays' && feedInfo.id
|
||||
? relaySets.find((set) => set.id === feedInfo.id)
|
||||
? (relaySets.find((set) => set.id === feedInfo.id) ??
|
||||
COMMUNITY_RELAY_SETS.find((set) => set.id === feedInfo.id))
|
||||
: undefined
|
||||
}, [feedInfo, relaySets])
|
||||
const title = useMemo(() => {
|
||||
|
|
@ -78,7 +84,7 @@ const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEle
|
|||
return simplifyUrl(feedInfo?.id ?? '')
|
||||
}
|
||||
if (feedInfo?.feedType === 'relays') {
|
||||
return activeRelaySet?.name ?? activeRelaySet?.id
|
||||
return feedInfo.name ?? activeRelaySet?.name ?? activeRelaySet?.id
|
||||
}
|
||||
}, [feedInfo, activeRelaySet])
|
||||
|
||||
|
|
@ -92,15 +98,22 @@ const FeedSwitcherTrigger = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivEle
|
|||
return <Server />
|
||||
}, [feedInfo])
|
||||
|
||||
const clickable =
|
||||
!IS_COMMUNITY_MODE || COMMUNITY_RELAY_SETS.length + COMMUNITY_RELAYS.length > 1
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn('clickable flex h-full items-center gap-2 rounded-xl px-3', className)}
|
||||
className={cn(
|
||||
'flex h-full items-center gap-2 rounded-xl px-3',
|
||||
clickable && 'clickable',
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
{icon}
|
||||
<div className="truncate text-lg font-semibold">{title}</div>
|
||||
<ChevronDown />
|
||||
{clickable && <ChevronDown />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { usePrimaryPage, useSecondaryPage } from '@/PageManager'
|
||||
import FollowingFeed from '@/components/FollowingFeed'
|
||||
import PostEditor from '@/components/PostEditor'
|
||||
import RelayInfo from '@/components/RelayInfo'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
|
@ -21,7 +22,6 @@ import {
|
|||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import FeedButton from './FeedButton'
|
||||
import FollowingFeed from './FollowingFeed'
|
||||
import PinnedFeed from './PinnedFeed'
|
||||
import RelaysFeed from './RelaysFeed'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import MailboxSetting from '@/components/MailboxSetting'
|
||||
import FavoriteRelaysSetting from '@/components/FavoriteRelaysSetting'
|
||||
import MailboxSetting from '@/components/MailboxSetting'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { IS_COMMUNITY_MODE } from '@/constants'
|
||||
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
|
||||
import { forwardRef, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
|
@ -20,6 +21,16 @@ const RelaySettingsPage = forwardRef(({ index }: { index?: number }, ref) => {
|
|||
}
|
||||
}, [])
|
||||
|
||||
if (IS_COMMUNITY_MODE) {
|
||||
return (
|
||||
<SecondaryPageLayout ref={ref} index={index} title={t('Relay settings')}>
|
||||
<div className="space-y-4 px-4 py-3">
|
||||
<MailboxSetting />
|
||||
</div>
|
||||
</SecondaryPageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<SecondaryPageLayout ref={ref} index={index} title={t('Relay settings')}>
|
||||
<Tabs value={tabValue} onValueChange={setTabValue} className="space-y-4 px-4 py-3">
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { IS_COMMUNITY_MODE, COMMUNITY_RELAY_SETS } from '@/constants'
|
||||
import { createFavoriteRelaysDraftEvent, createRelaySetDraftEvent } from '@/lib/draft-event'
|
||||
import { formatError } from '@/lib/error'
|
||||
import { getReplaceableEventIdentifier } from '@/lib/event'
|
||||
|
|
@ -44,6 +45,10 @@ export function FavoriteRelaysProvider({ children }: { children: React.ReactNode
|
|||
const [relaySets, setRelaySets] = useState<TRelaySet[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (IS_COMMUNITY_MODE) {
|
||||
setRelaySets(COMMUNITY_RELAY_SETS)
|
||||
return
|
||||
}
|
||||
if (!favoriteRelaysEvent) {
|
||||
const favoriteRelays: string[] = []
|
||||
const storedRelaySets = storage.getRelaySets()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { IS_COMMUNITY_MODE, COMMUNITY_RELAY_SETS, COMMUNITY_RELAYS } from '@/constants'
|
||||
import { getRelaySetFromEvent } from '@/lib/event-metadata'
|
||||
import { isWebsocketUrl, normalizeUrl } from '@/lib/url'
|
||||
import indexedDb from '@/services/indexed-db.service'
|
||||
import storage from '@/services/local-storage.service'
|
||||
import { TFeedInfo, TFeedType } from '@/types'
|
||||
import { TFeedInfo, TFeedType, TRelaySet } from '@/types'
|
||||
import { kinds } from 'nostr-tools'
|
||||
import { createContext, useContext, useEffect, useRef, useState } from 'react'
|
||||
import { useFavoriteRelays } from './FavoriteRelaysProvider'
|
||||
|
|
@ -48,9 +49,21 @@ export function FeedProvider({ children }: { children: React.ReactNode }) {
|
|||
if (storedFeedInfo) {
|
||||
feedInfo = storedFeedInfo
|
||||
} else {
|
||||
feedInfo = { feedType: 'following' }
|
||||
if (!IS_COMMUNITY_MODE) {
|
||||
feedInfo = { feedType: 'following' }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!feedInfo && IS_COMMUNITY_MODE) {
|
||||
feedInfo =
|
||||
COMMUNITY_RELAY_SETS.length > 0
|
||||
? {
|
||||
feedType: 'relays',
|
||||
id: COMMUNITY_RELAY_SETS[0].id,
|
||||
name: COMMUNITY_RELAY_SETS[0].name
|
||||
}
|
||||
: { feedType: 'relay', id: COMMUNITY_RELAYS[0] }
|
||||
}
|
||||
|
||||
if (feedInfo?.feedType === 'relays') {
|
||||
return await switchFeed('relays', { activeRelaySetId: feedInfo.id })
|
||||
|
|
@ -109,24 +122,33 @@ export function FeedProvider({ children }: { children: React.ReactNode }) {
|
|||
}
|
||||
if (feedType === 'relays') {
|
||||
const relaySetId = options.activeRelaySetId ?? (relaySets.length > 0 ? relaySets[0].id : null)
|
||||
if (!relaySetId || !pubkey) {
|
||||
setIsReady(true)
|
||||
return
|
||||
}
|
||||
let relaySet: TRelaySet | null = null
|
||||
if (IS_COMMUNITY_MODE) {
|
||||
relaySet =
|
||||
COMMUNITY_RELAY_SETS.find((set) => set.id === relaySetId) ??
|
||||
(COMMUNITY_RELAY_SETS.length > 0 ? COMMUNITY_RELAY_SETS[0] : null)
|
||||
} else {
|
||||
if (!relaySetId || !pubkey) {
|
||||
setIsReady(true)
|
||||
return
|
||||
}
|
||||
|
||||
let relaySet =
|
||||
relaySets.find((set) => set.id === relaySetId) ??
|
||||
(relaySets.length > 0 ? relaySets[0] : null)
|
||||
if (!relaySet) {
|
||||
const storedRelaySetEvent = await indexedDb.getReplaceableEvent(
|
||||
pubkey,
|
||||
kinds.Relaysets,
|
||||
relaySetId
|
||||
)
|
||||
if (storedRelaySetEvent) {
|
||||
relaySet = getRelaySetFromEvent(storedRelaySetEvent)
|
||||
relaySet =
|
||||
relaySets.find((set) => set.id === relaySetId) ??
|
||||
(relaySets.length > 0 ? relaySets[0] : null)
|
||||
|
||||
if (!relaySet) {
|
||||
const storedRelaySetEvent = await indexedDb.getReplaceableEvent(
|
||||
pubkey,
|
||||
kinds.Relaysets,
|
||||
relaySetId
|
||||
)
|
||||
if (storedRelaySetEvent) {
|
||||
relaySet = getRelaySetFromEvent(storedRelaySetEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (relaySet) {
|
||||
const newFeedInfo = { feedType, id: relaySet.id }
|
||||
setFeedInfo(newFeedInfo)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import BookmarkPage from '@/pages/primary/BookmarkPage'
|
||||
import ExplorePage from '@/pages/primary/ExplorePage'
|
||||
import FollowingPage from '@/pages/primary/FollowingPage'
|
||||
import MePage from '@/pages/primary/MePage'
|
||||
import NoteListPage from '@/pages/primary/NoteListPage'
|
||||
import NotificationListPage from '@/pages/primary/NotificationListPage'
|
||||
|
|
@ -13,6 +14,7 @@ import { createRef } from 'react'
|
|||
const PRIMARY_ROUTE_CONFIGS = [
|
||||
{ key: 'home', component: NoteListPage },
|
||||
{ key: 'explore', component: ExplorePage },
|
||||
{ key: 'following', component: FollowingPage },
|
||||
{ key: 'notifications', component: NotificationListPage },
|
||||
{ key: 'me', component: MePage },
|
||||
{ key: 'profile', component: ProfilePage },
|
||||
|
|
|
|||
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
|
|
@ -114,7 +114,7 @@ export type TAccount = {
|
|||
export type TAccountPointer = Pick<TAccount, 'pubkey' | 'signerType'>
|
||||
|
||||
export type TFeedType = 'following' | 'pinned' | 'relays' | 'relay'
|
||||
export type TFeedInfo = { feedType: TFeedType; id?: string } | null
|
||||
export type TFeedInfo = { feedType: TFeedType; id?: string; name?: string } | null
|
||||
|
||||
export type TLanguage = 'en' | 'zh' | 'pl'
|
||||
|
||||
|
|
|
|||
4
src/vite-env.d.ts
vendored
4
src/vite-env.d.ts
vendored
|
|
@ -6,3 +6,7 @@ declare global {
|
|||
nostr?: TNip07
|
||||
}
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue