import { msg } from "@lingui/core/macro" import { useLingui } from "@lingui/react" import { Box, Center, CloseButton, Divider, Group, Indicator, Popover, TextInput } from "@mantine/core" import { useForm } from "@mantine/form" import { useElementSize, useViewportSize } from "@mantine/hooks" import { type ReactNode, type RefCallback, useEffect } from "react" import { TbArrowDown, TbArrowUp, TbChecks, TbExternalLink, TbEye, TbEyeOff, TbRefresh, TbSearch, TbSettings, TbSortAscending, TbSortDescending, TbUser, } from "react-icons/tb" import { markAllAsReadWithConfirmationIfRequired, reloadEntries, search, selectNextEntry, selectPreviousEntry } from "@/app/entries/thunks" import { useAppDispatch, useAppSelector } from "@/app/store" import { changeSettings } from "@/app/user/thunks" import { ActionButton, type Mode } from "@/components/ActionButton" import { Loader } from "@/components/Loader" import { useActionButton } from "@/hooks/useActionButton" import { useBrowserExtension } from "@/hooks/useBrowserExtension" import { useMobile } from "@/hooks/useMobile" import { ProfileMenu } from "./ProfileMenu" function HeaderDivider() { return } function HeaderToolbar(props: { children: ReactNode; ref?: RefCallback }) { const { spacing } = useActionButton() const mobile = useMobile("480px") return mobile ? ( // on mobile use all available width {props.children} ) : ( {props.children} ) } const iconSize = 18 export function Header() { const settings = useAppSelector(state => state.user.settings) const profile = useAppSelector(state => state.user.profile) const searchFromStore = useAppSelector(state => state.entries.search) const { isBrowserExtensionPopup, openSettingsPage, openAppInNewTab } = useBrowserExtension() const dispatch = useAppDispatch() const viewport = useViewportSize() const { ref: headerRef, width: headerWidth } = useElementSize() const sidebarWidth = useAppSelector(state => state.user.localSettings.sidebarWidth) const headerTooLarge = headerWidth > viewport.width - sidebarWidth const mode: Mode = headerTooLarge ? "mobile" : "auto" const { _ } = useLingui() const searchForm = useForm<{ search: string }>() const { setValues } = searchForm useEffect(() => { setValues({ search: searchFromStore, }) }, [setValues, searchFromStore]) if (!settings) return const toggleReadingMode = async () => { await dispatch( changeSettings({ readingMode: settings.readingMode === "all" ? "unread" : "all", }) ) dispatch(reloadEntries()) } const toggleReadingOrder = async () => { await dispatch( changeSettings({ readingOrder: settings.readingOrder === "asc" ? "desc" : "asc", }) ) dispatch(reloadEntries()) } return (
} label={msg`Previous`} mode={mode} onClick={async () => await dispatch( selectPreviousEntry({ expand: true, markAsRead: true, scrollToEntry: true, }) ) } /> } label={msg`Next`} mode={mode} onClick={async () => await dispatch( selectNextEntry({ expand: true, markAsRead: true, scrollToEntry: true, }) ) } /> } label={msg`Refresh`} mode={mode} onClick={async () => await dispatch(reloadEntries())} /> } label={msg`Mark all as read`} mode={mode} onClick={() => dispatch(markAllAsReadWithConfirmationIfRequired())} /> : } label={settings.readingMode === "all" ? msg`All` : msg`Unread`} mode={mode} onClick={toggleReadingMode} /> : } label={settings.readingOrder === "asc" ? msg`Asc` : msg`Desc`} mode={mode} onClick={toggleReadingOrder} /> } label={msg`Search`} mode={mode} />
await dispatch(search(values.search)))}> } rightSection={ await (searchFromStore && dispatch(search("")))} />} autoFocus />
} label={profile?.name} mode={mode} />} /> {isBrowserExtensionPopup && ( <> } label={msg`Extension options`} mode={mode} onClick={() => openSettingsPage()} /> } label={msg`Open CommaFeed`} mode={mode} onClick={() => openAppInNewTab()} /> )}
) }