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,
|
||||
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"
|
||||
|
|
|
|||
Loading…
Reference in a new issue