ui: quiet and compact desktop status control

This commit is contained in:
SkateSpots 2026-10-31 16:57:42 +07:00
parent 0fe82c28d8
commit f646d5aa14

View file

@ -54,9 +54,11 @@ import {
ChevronDown,
ArrowLeft,
Search,
SmilePlus,
} from 'lucide-react';
import { OfflineIndicator } from '@/components/OfflineIndicator';
import { UserStatusIndicator } from '@/components/UserStatusIndicator';
import { SKATING_STATUSES, useUserStatus } from '@/hooks/useUserStatus';
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
import { useAuthor } from '@/hooks/useAuthor';
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) {
const location = useLocation();
const navigate = useNavigate();
@ -752,20 +793,7 @@ export function Layout({ children, noPadding }: LayoutProps) {
</Link>
)}
{/* Status Quick Access - Desktop */}
{user && (
<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>
)}
{user && <DesktopStatusButton onOpen={() => setShowStatusDialog(true)} />}
<Button
variant="ghost"
size="icon"