add context menu for groupsidebar

This commit is contained in:
pa
2026-03-06 23:26:20 +09:00
parent cf1577cb44
commit 2450971211
2 changed files with 74 additions and 21 deletions

View File

@@ -30,22 +30,41 @@
</template>
<template v-else-if="item.row.type === 'group-item'">
<div class="x-friend-item" @click="showGroupDialog(item.row.ownerId)">
<template v-if="item.row.isVisible">
<div class="avatar">
<img :src="getSmallGroupIconUrl(item.row.iconUrl)" loading="lazy" />
<ContextMenu>
<ContextMenuTrigger as-child>
<div class="x-friend-item" @click="showGroupDialog(item.row.ownerId)">
<template v-if="item.row.isVisible">
<div class="avatar">
<img :src="getSmallGroupIconUrl(item.row.iconUrl)" loading="lazy" />
</div>
<div class="detail">
<span class="name">
<span v-text="item.row.name"></span>
<span class="ml-1.5 font-normal">
({{ item.row.userCount }}/{{ item.row.capacity }})
</span>
</span>
<Location
class="text-xs"
:location="item.row.location"
:link="false" />
</div>
</template>
</div>
<div class="detail">
<span class="name">
<span v-text="item.row.name"></span>
<span class="ml-1.5 font-normal">
({{ item.row.userCount }}/{{ item.row.capacity }})
</span>
</span>
<Location class="text-xs" :location="item.row.location" :link="false" />
</div>
</template>
</div>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem
:disabled="!checkCanInviteSelf(item.row.location)"
@click="groupInstanceLaunch(item.row.location)">
{{ t('dialog.user.info.launch_invite_tooltip') }}
</ContextMenuItem>
<ContextMenuItem
:disabled="!checkCanInviteSelf(item.row.location)"
@click="groupInstanceSelfInvite(item.row.location)">
{{ t('dialog.user.info.self_invite_tooltip') }}
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</template>
</div>
</template>
@@ -60,15 +79,27 @@
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { ChevronDown } from 'lucide-vue-next';
import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
import { useVirtualizer } from '@tanstack/vue-virtual';
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuTrigger
} from '../../../components/ui/context-menu';
import { buildGroupHeaderRow, buildGroupItemRow, estimateGroupRowSize, getGroupId } from '../groupsSidebarUtils';
import { useAppearanceSettingsStore, useGroupStore } from '../../../stores';
import { convertFileUrlToImageUrl } from '../../../shared/utils';
import { checkCanInviteSelf, convertFileUrlToImageUrl, parseLocation } from '../../../shared/utils';
import { useAppearanceSettingsStore, useGroupStore, useLaunchStore } from '../../../stores';
import { instanceRequest } from '../../../api';
import BackToTop from '../../../components/BackToTop.vue';
import Location from '../../../components/Location.vue';
const { t } = useI18n();
const launchStore = useLaunchStore();
const { isAgeGatedInstancesVisible } = storeToRefs(useAppearanceSettingsStore());
const { showGroupDialog, sortGroupInstancesByInGame } = useGroupStore();
const { groupInstances } = storeToRefs(useGroupStore());
@@ -164,6 +195,31 @@
groupInstancesCfg.value[groupId].isCollapsed = !groupInstancesCfg.value[groupId].isCollapsed;
}
/**
* @param {string} location - Instance location tag
*/
function groupInstanceLaunch(location) {
if (!location) return;
launchStore.showLaunchDialog(location);
}
/**
* @param {string} location - Instance location tag
*/
function groupInstanceSelfInvite(location) {
if (!location) return;
const L = parseLocation(location);
if (!L.isRealInstance) return;
instanceRequest
.selfInvite({
instanceId: L.instanceId,
worldId: L.worldId
})
.then(() => {
toast.success(t('message.invite.self_sent'));
});
}
onMounted(() => {
nextTick(() => {
virtualizer.value?.measure?.();