import { useEffect } from 'react';
import { Outlet, resolveMeta, useRoute } from '@oomfware/stacker';
import { useKeybind } from '#/lib/keybinds';
import { focusSearch } from '#/state/events';
import { useSession } from '#/state/session';
import { closeAllActiveElements } from '#/state/shell/overlays';
import { useOpenComposer } from '#/features/composer/open-composer';
import { LinkWarningDialog } from '#/components/dialogs/LinkWarningDialog';
import { SigninDialog } from '#/components/dialogs/Signin';
import { ErrorBoundary } from '#/components/ErrorBoundary';
import { GroupChatJoinDialog } from '#/components/intents/GroupChatJoinDialog';
import { Lightbox } from '#/components/Lightbox';
import { GlobalReportDialog } from '#/components/moderation/ReportDialog';
import { LoggedOut } from '#/components/Shell/LoggedOut';
import { Shell } from '#/components/Shell/Shell';
import { useRouter } from '#/router';
import { ComposerDialog } from './ComposerDialog';
/**
* the shell layout wrapping every in-app route. global overlays live inside here (not as siblings of the
* router) so their virtualized lists read `useIsFocused()` as `true`.
*/
export function ShellLayout() {
const match = useRoute();
const router = useRouter();
const { hasSession } = useSession();
const { openComposer } = useOpenComposer();
useKeybind({
scope: 'app',
keybind: 'n',
enabled: hasSession,
handle() {
openComposer({});
},
});
useKeybind({
scope: 'app',
keybind: '/',
handle() {
if (!focusSearch.emit()) {
router.navigate({ to: { name: 'Explore' } });
}
},
});
// close dialogs/menus/lightbox when the history entry changes, but NOT on an in-place replace (which
// also fires subscribe) — gate on the entry key so clearing a one-shot param can't dismiss the composer.
useEffect(() => {
let prevKey = router.location.key;
return router.subscribe(() => {
const key = router.location.key;
if (key !== prevKey) {
prevKey = key;
closeAllActiveElements();
}
});
}, [router]);
if (!hasSession && resolveMeta(match, 'requireAuth')) {
return ;
}
return (
);
}