Add profile control at the bottom

merge-requests/3312/head
Alex Gleason 2025-01-24 23:22:35 -06:00
rodzic 4498130f23
commit f56dabe458
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
3 zmienionych plików z 112 dodań i 97 usunięć

Wyświetl plik

@ -23,11 +23,13 @@ import worldIcon from '@tabler/icons/outline/world.svg';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import Account from 'soapbox/components/account.tsx';
import SiteLogo from 'soapbox/components/site-logo.tsx'; import SiteLogo from 'soapbox/components/site-logo.tsx';
import Stack from 'soapbox/components/ui/stack.tsx'; import Stack from 'soapbox/components/ui/stack.tsx';
import { useStatContext } from 'soapbox/contexts/stat-context.tsx'; import { useStatContext } from 'soapbox/contexts/stat-context.tsx';
import Search from 'soapbox/features/compose/components/search.tsx'; import Search from 'soapbox/features/compose/components/search.tsx';
import ComposeButton from 'soapbox/features/ui/components/compose-button.tsx'; import ComposeButton from 'soapbox/features/ui/components/compose-button.tsx';
import ProfileDropdown from 'soapbox/features/ui/components/profile-dropdown.tsx';
import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts'; import { useAppSelector } from 'soapbox/hooks/useAppSelector.ts';
import { useFeatures } from 'soapbox/hooks/useFeatures.ts'; import { useFeatures } from 'soapbox/hooks/useFeatures.ts';
import { useInstance } from 'soapbox/hooks/useInstance.ts'; import { useInstance } from 'soapbox/hooks/useInstance.ts';
@ -142,6 +144,7 @@ const SidebarNavigation = () => {
}; };
return ( return (
<Stack justifyContent='between' className='min-h-screen py-6'>
<Stack space={6}> <Stack space={6}>
<Link key='logo' to='/' data-preview-title-id='column.home' className='ml-4 flex shrink-0 items-center'> <Link key='logo' to='/' data-preview-title-id='column.home' className='ml-4 flex shrink-0 items-center'>
<SiteLogo alt='Logo' className='h-10 w-auto cursor-pointer' /> <SiteLogo alt='Logo' className='h-10 w-auto cursor-pointer' />
@ -245,6 +248,17 @@ const SidebarNavigation = () => {
<ComposeButton /> <ComposeButton />
)} )}
</Stack> </Stack>
{account && (
<div className='mt-12'>
<ProfileDropdown account={account} placement='top'>
<div className='w-full p-2'>
<Account account={account} showProfileHoverCard={false} withLinkToProfile={false} hideActions />
</div>
</ProfileDropdown>
</div>
)}
</Stack>
); );
}; };

Wyświetl plik

@ -31,7 +31,7 @@ const Layout: LayoutComponent = ({ children }) => (
/** Left sidebar container in the UI. */ /** Left sidebar container in the UI. */
const Sidebar: React.FC<ISidebar> = ({ children }) => ( const Sidebar: React.FC<ISidebar> = ({ children }) => (
<div className='hidden lg:col-span-3 lg:block'> <div className='hidden lg:col-span-3 lg:block'>
<StickyBox className='py-6'> <StickyBox>
{children} {children}
</StickyBox> </StickyBox>
</div> </div>

Wyświetl plik

@ -1,4 +1,4 @@
import { useFloating } from '@floating-ui/react'; import { Placement, useFloating } from '@floating-ui/react';
import logoutIcon from '@tabler/icons/outline/logout.svg'; import logoutIcon from '@tabler/icons/outline/logout.svg';
import plusIcon from '@tabler/icons/outline/plus.svg'; import plusIcon from '@tabler/icons/outline/plus.svg';
import clsx from 'clsx'; import clsx from 'clsx';
@ -29,6 +29,7 @@ const messages = defineMessages({
interface IProfileDropdown { interface IProfileDropdown {
account: AccountEntity; account: AccountEntity;
children: React.ReactNode; children: React.ReactNode;
placement?: Placement;
} }
type IMenuItem = { type IMenuItem = {
@ -39,13 +40,13 @@ type IMenuItem = {
action?: (event: React.MouseEvent) => void; action?: (event: React.MouseEvent) => void;
} }
const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => { const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children, placement = 'bottom-end' }) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const features = useFeatures(); const features = useFeatures();
const intl = useIntl(); const intl = useIntl();
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const { x, y, strategy, refs } = useFloating<HTMLButtonElement>({ placement: 'bottom-end' }); const { x, y, strategy, refs } = useFloating<HTMLButtonElement>({ placement });
const getOtherAccounts = useCallback(makeGetOtherAccounts(), []); const getOtherAccounts = useCallback(makeGetOtherAccounts(), []);
const otherAccounts = useAppSelector((state) => getOtherAccounts(state)); const otherAccounts = useAppSelector((state) => getOtherAccounts(state));
@ -117,7 +118,7 @@ const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
return ( return (
<> <>
<button <button
className='rounded-full focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 dark:ring-gray-800 dark:ring-offset-0 dark:focus:ring-primary-500' className='w-full rounded-full focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 dark:ring-gray-800 dark:ring-offset-0 dark:focus:ring-primary-500'
type='button' type='button'
ref={refs.setReference} ref={refs.setReference}
onClick={toggleVisible} onClick={toggleVisible}