import { type Accessor, type Component, type ComponentProps, ErrorBoundary, Suspense, createMemo, lazy, } from 'solid-js'; import type { AppBskyNotificationGetUnreadCount } from '@atcute/bluesky'; import type { DefinedCreateQueryResult } from '@mary/solid-query'; import { createNotificationCountQuery } from '~/api/queries/notification-count'; import { globalEvents } from '~/globals/events'; import { hasModals } from '~/globals/modals'; import { history } from '~/globals/navigation'; import { type MatchedRouteState, RouterView, useMatchedRoute } from '~/lib/navigation/router'; import { useSession } from '~/lib/states/session'; import BellOutlinedIcon from '~/components/icons-central/bell-outline'; import BellSolidIcon from '~/components/icons-central/bell-solid'; import HomeOutlinedIcon from '~/components/icons-central/home-outline'; import HomeSolidIcon from '~/components/icons-central/home-solid'; import MagnifyingGlassOutlinedIcon from '~/components/icons-central/magnifying-glass-outline'; import MailOutlinedIcon from '~/components/icons-central/mail-outline'; import MailSolidIcon from '~/components/icons-central/mail-solid'; import ErrorPage from '~/views/_error'; const SignedOutView = lazy(() => import('~/views/_signed-out')); const Shell = () => { const { currentAccount } = useSession(); // Will always match because we've set a 404 handler. const route = useMatchedRoute() as Accessor; const showNavBar = createMemo((): boolean => { return !!(currentAccount && route().def.meta?.main); }); const unread = createNotificationCountQuery({ get disabled() { return !showNavBar(); }, }); return (
{!!(currentAccount && route().def.meta?.main) && }
{ return ( }> { if (!currentAccount && !def.meta?.public) { return ; } return ; })()} /> ); }} />
); }; export default Shell; const enum MainTabs { HOME = 'Home', EXPLORE = 'Explore', NOTIFICATIONS = 'Notifications', MESSAGES = 'Messages', } const MainTabsRoutes = { [MainTabs.HOME]: '/', [MainTabs.EXPLORE]: '/explore', [MainTabs.NOTIFICATIONS]: '/notifications', [MainTabs.MESSAGES]: '/messages', }; const NavBar = ({ route, unread, }: { route: Accessor; unread: DefinedCreateQueryResult; }) => { const active = () => route().def.meta?.name; const bindClick = (to: MainTabs) => { return () => { const from = active(); if (from === to) { window.scrollTo({ top: 0, behavior: 'instant' }); globalEvents.emit('softreset'); return; } const fromHome = !!(history.location.state as any)?.fromHome; const href = MainTabsRoutes[to]; if (to === MainTabs.HOME && fromHome) { history.back(); return; } history.navigate(href, { replace: from !== MainTabs.HOME, state: { // inherit `fromHome` state fromHome: fromHome || from === MainTabs.HOME, }, }); }; }; return ( <>
); }; const getUnreadCountLabel = (count: number = 0) => { return count > 0 ? (count > 30 ? `30+` : `${count}`) : ``; }; type IconComponent = Component>; interface NavItemProps { active?: boolean; label: string; badge?: string; icon: IconComponent; iconActive?: IconComponent; onClick?: () => void; } const NavItem = (props: NavItemProps) => { const InactiveIcon = props.icon; const ActiveIcon = props.iconActive; return ( ); };