118 lines
3.8 KiB
TypeScript
Raw Normal View History

2022-05-12 02:45:43 +08:00
import SvgIcon from '@/web/components/SvgIcon'
import useScroll from '@/web/hooks/useScroll'
import { useState, useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import Avatar from './Avatar'
2022-05-12 02:45:43 +08:00
import cx from 'classnames'
2022-03-13 14:40:38 +08:00
const NavigationButtons = () => {
const navigate = useNavigate()
enum ACTION {
Back = 'back',
Forward = 'forward',
2022-03-13 14:40:38 +08:00
}
const handleNavigate = (action: ACTION) => {
if (action === ACTION.Back) navigate(-1)
if (action === ACTION.Forward) navigate(1)
2022-03-13 14:40:38 +08:00
}
return (
2022-03-17 19:30:43 +08:00
<div className='flex gap-1'>
{[ACTION.Back, ACTION.Forward].map(action => (
2022-03-13 14:40:38 +08:00
<div
onClick={() => handleNavigate(action)}
key={action}
2022-03-21 02:03:25 +08:00
className='app-region-no-drag btn-hover-animation rounded-lg p-2 text-gray-500 transition duration-300 after:rounded-full after:bg-black/[.06] hover:text-gray-900 dark:text-gray-300 dark:after:bg-white/10 dark:hover:text-gray-200'
2022-03-13 14:40:38 +08:00
>
2022-03-21 02:03:25 +08:00
<SvgIcon className='h-5 w-5' name={action} />
2022-03-13 14:40:38 +08:00
</div>
))}
</div>
)
}
const SearchBox = () => {
2022-03-29 00:11:05 +08:00
const { type } = useParams()
const [keywords, setKeywords] = useState('')
2022-03-27 15:21:48 +08:00
const navigate = useNavigate()
const toSearch = (e: React.KeyboardEvent) => {
2022-03-29 00:11:05 +08:00
if (!keywords) return
2022-03-27 15:21:48 +08:00
if (e.key === 'Enter') {
2022-03-29 00:11:05 +08:00
navigate(`/search/${keywords}${type ? `/${type}` : ''}`)
2022-03-27 15:21:48 +08:00
}
}
2022-03-13 14:40:38 +08:00
return (
2022-03-27 15:21:48 +08:00
<div className='app-region-no-drag group flex w-[16rem] cursor-text items-center rounded-full bg-gray-500 bg-opacity-5 pl-2.5 pr-2 transition duration-300 hover:bg-opacity-10 dark:bg-gray-300 dark:bg-opacity-5'>
2022-03-13 14:40:38 +08:00
<SvgIcon
2022-03-27 15:21:48 +08:00
className='mr-2 h-4 w-4 text-gray-500 transition duration-300 group-hover:text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-200'
2022-03-17 19:30:43 +08:00
name='search'
2022-03-13 14:40:38 +08:00
/>
<input
2022-03-29 00:11:05 +08:00
value={keywords}
onChange={e => setKeywords(e.target.value)}
2022-03-27 15:21:48 +08:00
onKeyDown={toSearch}
2022-03-17 19:30:43 +08:00
type='text'
2022-03-27 15:21:48 +08:00
className='flex-grow bg-transparent placeholder:text-gray-500 dark:text-white dark:placeholder:text-gray-400'
2022-03-21 02:03:25 +08:00
placeholder='搜索'
2022-03-13 14:40:38 +08:00
/>
2022-03-27 15:21:48 +08:00
<div
2022-03-29 00:11:05 +08:00
onClick={() => setKeywords('')}
2022-05-12 02:45:43 +08:00
className={cx(
'cursor-default rounded-full p-1 text-gray-600 transition hover:bg-gray-400/20 dark:text-white/50 dark:hover:bg-white/20',
2022-03-29 00:11:05 +08:00
!keywords && 'hidden'
2022-03-27 15:21:48 +08:00
)}
>
<SvgIcon className='h-4 w-4' name='x' />
</div>
2022-03-13 14:40:38 +08:00
</div>
)
}
const Settings = () => {
const navigate = useNavigate()
2022-03-13 14:40:38 +08:00
return (
2022-04-02 02:12:15 +08:00
<div
onClick={() => navigate('/settings')}
2022-04-02 02:12:15 +08:00
className='app-region-no-drag btn-hover-animation rounded-lg p-2.5 text-gray-500 transition duration-300 after:rounded-full after:bg-black/[.06] hover:text-gray-900 dark:text-gray-300 dark:after:bg-white/10 dark:hover:text-gray-200'
>
2022-03-21 02:03:25 +08:00
<SvgIcon className='h-[1.125rem] w-[1.125rem]' name='settings' />
2022-03-13 14:40:38 +08:00
</div>
)
}
const Topbar = () => {
/**
* Show topbar background when scroll down
*/
const [mainContainer, setMainContainer] = useState<HTMLElement | null>(null)
const scroll = useScroll(mainContainer, { throttle: 100 })
useEffect(() => {
setMainContainer(document.getElementById('mainContainer'))
}, [setMainContainer])
return (
<div
2022-05-12 02:45:43 +08:00
className={cx(
'sticky z-30 flex h-16 min-h-[4rem] w-full cursor-default items-center justify-between px-8 transition duration-300',
window.env?.isMac && 'app-region-drag',
window.env?.isEnableTitlebar ? 'top-8' : 'top-0',
2022-03-13 14:40:38 +08:00
!scroll.arrivedState.top &&
2022-03-17 14:45:04 +08:00
'bg-white bg-opacity-[.86] backdrop-blur-xl backdrop-saturate-[1.8] dark:bg-[#222] dark:bg-opacity-[.86]'
2022-03-13 14:40:38 +08:00
)}
>
2022-03-17 19:30:43 +08:00
<div className='flex gap-2'>
2022-03-13 14:40:38 +08:00
<NavigationButtons />
<SearchBox />
</div>
2022-03-17 19:30:43 +08:00
<div className='flex items-center gap-3'>
2022-03-13 14:40:38 +08:00
<Settings />
<Avatar />
</div>
</div>
)
}
export default Topbar