ui: quiet and compact desktop status control
This commit is contained in:
parent
0fe82c28d8
commit
f646d5aa14
1 changed files with 42 additions and 14 deletions
|
|
@ -54,9 +54,11 @@ import {
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
ArrowLeft,
|
ArrowLeft,
|
||||||
Search,
|
Search,
|
||||||
|
SmilePlus,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { OfflineIndicator } from '@/components/OfflineIndicator';
|
import { OfflineIndicator } from '@/components/OfflineIndicator';
|
||||||
import { UserStatusIndicator } from '@/components/UserStatusIndicator';
|
import { UserStatusIndicator } from '@/components/UserStatusIndicator';
|
||||||
|
import { SKATING_STATUSES, useUserStatus } from '@/hooks/useUserStatus';
|
||||||
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
|
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
|
||||||
import { useAuthor } from '@/hooks/useAuthor';
|
import { useAuthor } from '@/hooks/useAuthor';
|
||||||
import { genUserName } from '@/lib/genUserName';
|
import { genUserName } from '@/lib/genUserName';
|
||||||
|
|
@ -474,6 +476,45 @@ function MobileNav({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compact desktop status control. The old outlined pill + permanent ping read
|
||||||
|
* like an alert; this shows the current status as a quiet chip and falls back
|
||||||
|
* to a neutral "Status" affordance when none is set.
|
||||||
|
*/
|
||||||
|
function DesktopStatusButton({ onOpen }: { onOpen: () => void }) {
|
||||||
|
const { user } = useCurrentUser();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { data: status } = useUserStatus(user?.pubkey);
|
||||||
|
const preset = status?.statusId
|
||||||
|
? SKATING_STATUSES.find((item) => item.id === status.statusId)
|
||||||
|
: null;
|
||||||
|
const label = preset ? t(preset.labelKey) : status?.status;
|
||||||
|
const emoji = status?.emoji || preset?.emoji;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
onClick={onOpen}
|
||||||
|
title={t('chromeUi.setYourStatus')}
|
||||||
|
aria-label={t('chromeUi.setYourStatus')}
|
||||||
|
className={cn(
|
||||||
|
'h-9 gap-1.5 rounded-full border border-white/10 px-2.5 text-gray-300',
|
||||||
|
'hover:border-green-500/30 hover:bg-green-500/10 hover:text-green-300',
|
||||||
|
status && 'border-green-500/20 bg-green-500/5 text-green-200',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{emoji ? (
|
||||||
|
<span className="text-base leading-none" aria-hidden="true">{emoji}</span>
|
||||||
|
) : (
|
||||||
|
<SmilePlus className="h-4 w-4 text-green-400/80" />
|
||||||
|
)}
|
||||||
|
<span className="hidden max-w-[7rem] truncate text-xs font-semibold lg:inline">
|
||||||
|
{label || t('chromeUi.status')}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function Layout({ children, noPadding }: LayoutProps) {
|
export function Layout({ children, noPadding }: LayoutProps) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -752,20 +793,7 @@ export function Layout({ children, noPadding }: LayoutProps) {
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
{/* Status Quick Access - Desktop */}
|
{/* Status Quick Access - Desktop */}
|
||||||
{user && (
|
{user && <DesktopStatusButton onOpen={() => setShowStatusDialog(true)} />}
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
className="gap-2 px-3 border-green-500/50 text-green-400 hover:text-green-300 hover:bg-green-500/10 hover:border-green-500"
|
|
||||||
onClick={() => setShowStatusDialog(true)}
|
|
||||||
title={t('chromeUi.setYourStatus')}
|
|
||||||
>
|
|
||||||
<span className="relative flex h-2.5 w-2.5">
|
|
||||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" />
|
|
||||||
<span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-green-500" />
|
|
||||||
</span>
|
|
||||||
<span className="text-sm font-bold">{t('chromeUi.status')}</span>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue