Add recent action indicators to friend context menu

This commit is contained in:
pa
2026-03-16 20:34:01 +09:00
parent 1b3e292883
commit 54572f9480
3 changed files with 25 additions and 12 deletions

View File

@@ -147,12 +147,18 @@
v-if="item.row.friend.state === 'online'"
@click="friendRequestInvite(item.row.friend)">
{{ t('dialog.user.actions.request_invite') }}
<ContextMenuShortcut v-if="isActionRecent(item.row.friend.id, 'Request Invite')">
<Clock class="size-3.5 text-muted-foreground" />
</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem
v-if="isGameRunning"
:disabled="!canInviteToMyLocation"
@click="friendInvite(item.row.friend)">
{{ t('dialog.user.actions.invite') }}
<ContextMenuShortcut v-if="isActionRecent(item.row.friend.id, 'Invite')">
<Clock class="size-3.5 text-muted-foreground" />
</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem
:disabled="!currentUser.isBoopingEnabled"
@@ -193,7 +199,7 @@
<script setup>
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { ChevronDown, User } from 'lucide-vue-next';
import { ChevronDown, Clock, User } from 'lucide-vue-next';
import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
@@ -205,6 +211,7 @@
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuSub,
ContextMenuSubContent,
ContextMenuSubTrigger,
@@ -225,6 +232,7 @@
import { getFriendsSortFunction, isRealInstance } from '../../../shared/utils';
import { instanceRequest, notificationRequest, queryRequest, userRequest } from '../../../api';
import { useInviteChecks } from '../../../composables/useInviteChecks';
import { isActionRecent, recordRecentAction } from '../../../composables/useRecentActions';
import { useUserDisplay } from '../../../composables/useUserDisplay';
import { getFriendsLocations } from '../../../shared/utils/location.js';
import { parseLocation } from '../../../shared/utils';
@@ -793,6 +801,7 @@
*/
function friendRequestInvite(friend) {
notificationRequest.sendRequestInvite({ platform: 'standalonewindows' }, friend.id).then(() => {
recordRecentAction(friend.id, 'Request Invite');
toast.success('Request invite sent');
});
}
@@ -817,6 +826,7 @@
friend.id
)
.then(() => {
recordRecentAction(friend.id, 'Invite');
toast.success(t('message.invite.sent'));
});
});

View File

@@ -180,6 +180,7 @@ vi.mock('../../../../components/ui/context-menu', () => ({
'<button :disabled="disabled" @click="$emit(\'click\')"><slot /></button>'
},
ContextMenuSeparator: { template: '<hr />' },
ContextMenuShortcut: { template: '<span><slot /></span>' },
ContextMenuSub: { template: '<div><slot /></div>' },
ContextMenuSubContent: { template: '<div><slot /></div>' },
ContextMenuSubTrigger: { template: '<div><slot /></div>' },
@@ -210,9 +211,15 @@ vi.mock('../FriendItem.vue', () => ({
vi.mock('lucide-vue-next', () => ({
ChevronDown: { template: '<span data-testid="chevron" />' },
Clock: { template: '<span data-testid="clock" />' },
User: { template: '<i />' }
}));
vi.mock('../../../../composables/useRecentActions', () => ({
isActionRecent: vi.fn(() => false),
recordRecentAction: vi.fn()
}));
import FriendsSidebar from '../FriendsSidebar.vue';
function flushPromises() {

View File

@@ -182,18 +182,14 @@
{{ t('dialog.screenshot_metadata.section_players') }} ({{ screenshotMetadataDialog.metadata.players.length }})
</h4>
<div class="flex flex-wrap gap-1 max-h-[180px] overflow-y-auto">
<TooltipWrapper
<Badge
v-for="user in screenshotMetadataDialog.metadata.players"
:key="user.id"
side="top"
:content="user.pos ? '(' + user.pos.x + ', ' + user.pos.y + ', ' + user.pos.z + ')' : ''">
<Badge
variant="secondary"
class="cursor-pointer hover:bg-accent transition-colors"
@click="lookupUser(user)">
{{ user.displayName }}
</Badge>
</TooltipWrapper>
variant="secondary"
class="cursor-pointer hover:bg-accent transition-colors"
@click="lookupUser(user)">
{{ user.displayName }}
</Badge>
</div>
</div>
@@ -267,7 +263,7 @@
import { ButtonGroup } from '@/components/ui/button-group';
import { InputGroupSearch } from '@/components/ui/input-group';
import { Kbd } from '@/components/ui/kbd';
import { TooltipWrapper } from '@/components/ui/tooltip';
import { formatDateFilter } from '@/shared/utils';
import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner';