adjust navmenu context menu and my avatars ui

This commit is contained in:
pa
2026-03-08 16:50:21 +09:00
parent c0ce0ff1ea
commit 6d0cfdd8aa
4 changed files with 88 additions and 14 deletions

View File

@@ -148,6 +148,10 @@
<ContextMenuItem :disabled="!hasNotifications" @click="clearAllNotifications">
{{ t('nav_menu.mark_all_read') }}
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem @click="handleOpenCustomNavDialog">
{{ t('nav_menu.custom_nav.header') }}
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
@@ -361,7 +365,13 @@
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu';
import { computed, defineAsyncComponent, h, onMounted, ref, watch } from 'vue';
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from '@/components/ui/context-menu';
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuTrigger
} from '@/components/ui/context-menu';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { ChevronRight, Heart } from 'lucide-vue-next';
import { Kbd } from '@/components/ui/kbd';

View File

@@ -37,7 +37,7 @@
</Badge>
</Button>
</PopoverTrigger>
<PopoverContent class="w-auto p-3" align="start">
<PopoverContent class="w-80 p-3" align="start">
<div class="flex flex-col gap-3">
<Field>
<FieldLabel>{{ t('dialog.avatar.info.visibility') }}</FieldLabel>
@@ -177,6 +177,17 @@
class="cursor-pointer min-h-0">
<template #row-context-menu="{ row }">
<ContextMenuContent>
<ContextMenuItem @click="handleContextMenuAction('details', row.original)">
<Eye class="size-4" />
{{ t('dialog.avatar.actions.view_details') }}
</ContextMenuItem>
<ContextMenuItem
:disabled="row.original.id === currentAvatarId"
@click="handleContextMenuAction('wear', row.original)">
<Check class="size-4" />
{{ t('view.favorite.select_avatar_tooltip') }}
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem @click="handleContextMenuAction('manageTags', row.original)">
<Tag class="size-4" />
{{ t('dialog.avatar.actions.manage_tags') }}
@@ -284,6 +295,8 @@
<script setup>
import {
Check,
Eye,
Image as ImageIcon,
LayoutGrid,
List,

View File

@@ -13,6 +13,7 @@ import {
ArrowUpDown,
Check,
Ellipsis,
Eye,
Image,
Monitor,
Pencil,
@@ -94,7 +95,7 @@ export function getColumns({
<img
src={ref.thumbnailImageUrl}
class="cursor-pointer rounded-sm object-cover"
style="width: 36px; height: 24px;"
style="width: 34px; height: 22px;"
loading="lazy"
onClick={() => onShowAvatarDialog(ref.id)}
/>
@@ -137,7 +138,7 @@ export function getColumns({
const tags = row.original.$tags || [];
if (!tags.length) return null;
return (
<div class="flex flex-wrap gap-1">
<div class="flex flex-nowrap gap-1 overflow-hidden">
{tags.map((entry) => {
const hashColor = getTagColor(entry.tag);
const storedColor =
@@ -367,14 +368,21 @@ export function getColumns({
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
class="rounded-full"
size="icon-sm"
class="rounded-full h-6 w-6"
size="icon"
variant="ghost"
>
<Ellipsis class="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
onClick={() => onShowAvatarDialog(ref.id)}
>
<Eye class="size-4" />
{t('dialog.avatar.actions.view_details')}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() =>
onContextMenuAction('manageTags', ref)

View File

@@ -1,7 +1,7 @@
<template>
<HoverCard :open-delay="700" :close-delay="100">
<HoverCard :open="hoverOpen" :open-delay="700" :close-delay="100" @update:open="handleHoverOpen">
<HoverCardTrigger as="div">
<ContextMenu>
<ContextMenu @update:open="handleContextMenuOpen">
<ContextMenuTrigger as="div">
<div class="avatar-card-wrapper rounded-lg" @click="$emit('click')">
<Card
@@ -71,6 +71,10 @@
<Eye class="size-4" />
{{ t('dialog.avatar.actions.view_details') }}
</ContextMenuItem>
<ContextMenuItem :disabled="isActive" @click="emit('context-action', 'wear', avatar)">
<Check class="size-4" />
{{ t('view.favorite.select_avatar_tooltip') }}
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem @click="emit('context-action', 'manageTags', avatar)">
<Tag class="size-4" />
@@ -122,7 +126,16 @@
<HoverCardContent class="w-80 p-3 text-sm" side="right" :side-offset="8" align="start">
<div class="flex flex-col gap-2">
<!-- Name -->
<div class="font-medium text-base truncate">{{ avatar.name }}</div>
<div class="flex items-start gap-1">
<div class="font-medium text-base truncate flex-1 min-w-0">{{ avatar.name }}</div>
<Button
size="icon-sm"
variant="ghost"
class="shrink-0 size-6 rounded-full"
@click="emit('context-action', 'details', avatar)">
<ExternalLink class="size-3" />
</Button>
</div>
<!-- Tags -->
<div v-if="avatar.$tags?.length" class="flex flex-wrap gap-1">
@@ -154,9 +167,6 @@
</Badge>
</span>
<span class="text-muted-foreground">{{ t('dialog.avatar.info.version') }}</span>
<span>{{ avatar.version ?? '-' }}</span>
<span class="text-muted-foreground">{{ t('dialog.avatar.info.platform') }}</span>
<div class="flex items-center gap-1">
<Badge v-if="platformInfo.isPC" class="x-tag-platform-pc" variant="outline">
@@ -185,6 +195,9 @@
<span>{{ iosPerf }}</span>
</template>
<span class="text-muted-foreground">{{ t('dialog.avatar.info.version') }}</span>
<span>{{ avatar.version ?? '-' }}</span>
<template v-if="avatar.$timeSpent">
<span class="text-muted-foreground">{{ t('dialog.avatar.info.time_spent') }}</span>
<span>{{ timeToText(avatar.$timeSpent) }}</span>
@@ -202,7 +215,19 @@
</template>
<script setup>
import { Apple, Eye, Image as ImageIcon, Monitor, Pencil, RefreshCw, Smartphone, Tag, User } from 'lucide-vue-next';
import {
Apple,
Check,
ExternalLink,
Eye,
Image as ImageIcon,
Monitor,
Pencil,
RefreshCw,
Smartphone,
Tag,
User
} from 'lucide-vue-next';
import {
ContextMenu,
ContextMenuContent,
@@ -212,15 +237,33 @@
} from '@/components/ui/context-menu';
import { formatDateFilter, getAvailablePlatforms, getPlatformInfo, timeToText } from '@/shared/utils';
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
import { computed, ref } from 'vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import { computed } from 'vue';
import { getTagColor } from '@/shared/constants';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const hoverOpen = ref(false);
const contextMenuOpen = ref(false);
const handleContextMenuOpen = (open) => {
contextMenuOpen.value = open;
if (open) {
hoverOpen.value = false;
}
};
const handleHoverOpen = (open) => {
if (contextMenuOpen.value) {
return;
}
hoverOpen.value = open;
};
const props = defineProps({
avatar: {
type: Object,