mirror of
https://github.com/dergigi/boris.git
synced 2025-12-27 03:24:31 +01:00
174 lines
5.4 KiB
TypeScript
174 lines
5.4 KiB
TypeScript
import React, { useState } from 'react'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
import { faChevronRight, faRightFromBracket, faRightToBracket, faUserCircle, faGear, faHome, faPlus, faNewspaper, faTimes, faBolt } from '@fortawesome/free-solid-svg-icons'
|
|
import { Hooks } from 'applesauce-react'
|
|
import { useEventModel } from 'applesauce-react/hooks'
|
|
import { Models } from 'applesauce-core'
|
|
import { Accounts } from 'applesauce-accounts'
|
|
import { RelayPool } from 'applesauce-relay'
|
|
import IconButton from './IconButton'
|
|
import AddBookmarkModal from './AddBookmarkModal'
|
|
import { createWebBookmark } from '../services/webBookmarkService'
|
|
import { RELAYS } from '../config/relays'
|
|
|
|
interface SidebarHeaderProps {
|
|
onToggleCollapse: () => void
|
|
onLogout: () => void
|
|
onOpenSettings: () => void
|
|
relayPool: RelayPool | null
|
|
isMobile?: boolean
|
|
}
|
|
|
|
const SidebarHeader: React.FC<SidebarHeaderProps> = ({ onToggleCollapse, onLogout, onOpenSettings, relayPool, isMobile = false }) => {
|
|
const [isConnecting, setIsConnecting] = useState(false)
|
|
const [showAddModal, setShowAddModal] = useState(false)
|
|
const navigate = useNavigate()
|
|
const activeAccount = Hooks.useActiveAccount()
|
|
const accountManager = Hooks.useAccountManager()
|
|
const profile = useEventModel(Models.ProfileModel, activeAccount ? [activeAccount.pubkey] : null)
|
|
|
|
const handleLogin = async () => {
|
|
try {
|
|
setIsConnecting(true)
|
|
const account = await Accounts.ExtensionAccount.fromExtension()
|
|
accountManager.addAccount(account)
|
|
accountManager.setActive(account)
|
|
} catch (error) {
|
|
console.error('Login failed:', error)
|
|
alert('Login failed. Please install a nostr browser extension and try again.\n\nIf you aren\'t on nostr yet, start here: https://nstart.me/')
|
|
} finally {
|
|
setIsConnecting(false)
|
|
}
|
|
}
|
|
|
|
const getProfileImage = () => {
|
|
return profile?.picture || null
|
|
}
|
|
|
|
const getUserDisplayName = () => {
|
|
if (!activeAccount) return 'Unknown User'
|
|
if (profile?.name) return profile.name
|
|
if (profile?.display_name) return profile.display_name
|
|
if (profile?.nip05) return profile.nip05
|
|
return `${activeAccount.pubkey.slice(0, 8)}...${activeAccount.pubkey.slice(-8)}`
|
|
}
|
|
|
|
const handleSaveBookmark = async (url: string, title?: string, description?: string, tags?: string[]) => {
|
|
if (!activeAccount || !relayPool) {
|
|
throw new Error('Please login to create bookmarks')
|
|
}
|
|
|
|
await createWebBookmark(url, title, description, tags, activeAccount, relayPool, RELAYS)
|
|
}
|
|
|
|
const profileImage = getProfileImage()
|
|
|
|
return (
|
|
<>
|
|
<div className="sidebar-header-bar">
|
|
{isMobile ? (
|
|
<IconButton
|
|
icon={faTimes}
|
|
onClick={onToggleCollapse}
|
|
title="Close sidebar"
|
|
ariaLabel="Close sidebar"
|
|
variant="ghost"
|
|
className="mobile-close-btn"
|
|
/>
|
|
) : (
|
|
<button
|
|
onClick={onToggleCollapse}
|
|
className="toggle-sidebar-btn"
|
|
title="Collapse bookmarks sidebar"
|
|
aria-label="Collapse bookmarks sidebar"
|
|
>
|
|
<FontAwesomeIcon icon={faChevronRight} />
|
|
</button>
|
|
)}
|
|
<div className="sidebar-header-right">
|
|
<div
|
|
className="profile-avatar"
|
|
title={activeAccount ? getUserDisplayName() : "Login"}
|
|
onClick={
|
|
activeAccount
|
|
? () => navigate('/me')
|
|
: (isConnecting ? () => {} : handleLogin)
|
|
}
|
|
style={{ cursor: 'pointer' }}
|
|
>
|
|
{profileImage ? (
|
|
<img src={profileImage} alt={getUserDisplayName()} />
|
|
) : (
|
|
<FontAwesomeIcon icon={faUserCircle} />
|
|
)}
|
|
</div>
|
|
<IconButton
|
|
icon={faHome}
|
|
onClick={() => navigate('/')}
|
|
title="Home"
|
|
ariaLabel="Home"
|
|
variant="ghost"
|
|
/>
|
|
<IconButton
|
|
icon={faNewspaper}
|
|
onClick={() => navigate('/explore')}
|
|
title="Explore"
|
|
ariaLabel="Explore"
|
|
variant="ghost"
|
|
/>
|
|
<IconButton
|
|
icon={faBolt}
|
|
onClick={() => navigate('/support')}
|
|
title="Support"
|
|
ariaLabel="Support"
|
|
variant="ghost"
|
|
/>
|
|
<IconButton
|
|
icon={faGear}
|
|
onClick={onOpenSettings}
|
|
title="Settings"
|
|
ariaLabel="Settings"
|
|
variant="ghost"
|
|
/>
|
|
{activeAccount && (
|
|
<IconButton
|
|
icon={faPlus}
|
|
onClick={() => setShowAddModal(true)}
|
|
title="Add bookmark"
|
|
ariaLabel="Add bookmark"
|
|
variant="ghost"
|
|
/>
|
|
)}
|
|
{activeAccount ? (
|
|
<IconButton
|
|
icon={faRightFromBracket}
|
|
onClick={onLogout}
|
|
title="Logout"
|
|
ariaLabel="Logout"
|
|
variant="ghost"
|
|
/>
|
|
) : (
|
|
<IconButton
|
|
icon={faRightToBracket}
|
|
onClick={isConnecting ? () => {} : handleLogin}
|
|
title={isConnecting ? "Connecting..." : "Login"}
|
|
ariaLabel="Login"
|
|
variant="ghost"
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
{showAddModal && (
|
|
<AddBookmarkModal
|
|
onClose={() => setShowAddModal(false)}
|
|
onSave={handleSaveBookmark}
|
|
/>
|
|
)}
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default SidebarHeader
|
|
|