This commit is contained in:
pa
2026-01-07 23:24:54 +09:00
committed by Natsumi
parent dd45ca9545
commit a6b3244717
11 changed files with 928 additions and 847 deletions
@@ -222,94 +222,105 @@
style="margin-left: 5px" style="margin-left: 5px"
@click="selectAvatarWithoutConfirmation(avatarDialog.id)"></el-button> @click="selectAvatarWithoutConfirmation(avatarDialog.id)"></el-button>
</TooltipWrapper> </TooltipWrapper>
<el-dropdown trigger="click" style="margin-left: 5px" @command="avatarDialogCommand"> <DropdownMenu>
<el-button <DropdownMenuTrigger as-child>
:type="avatarDialog.isBlocked ? 'danger' : 'default'" <el-button
:icon="MoreFilled" :type="avatarDialog.isBlocked ? 'danger' : 'default'"
size="large" :icon="MoreFilled"
circle></el-button> size="large"
<template #dropdown> circle></el-button>
<el-dropdown-menu> </DropdownMenuTrigger>
<el-dropdown-item :icon="Refresh" command="Refresh">{{ <DropdownMenuContent>
t('dialog.avatar.actions.refresh') <DropdownMenuItem @click="avatarDialogCommand('Refresh')">
}}</el-dropdown-item> <Refresh class="size-4" />
<el-dropdown-item :icon="Share" command="Share">{{ {{ t('dialog.avatar.actions.refresh') }}
t('dialog.avatar.actions.share') </DropdownMenuItem>
}}</el-dropdown-item> <DropdownMenuItem @click="avatarDialogCommand('Share')">
<el-dropdown-item <Share class="size-4" />
v-if="avatarDialog.isBlocked" {{ t('dialog.avatar.actions.share') }}
:icon="CircleCheck" </DropdownMenuItem>
command="Unblock Avatar" <DropdownMenuSeparator />
style="color: #f56c6c" <DropdownMenuItem
divided v-if="avatarDialog.isBlocked"
>{{ t('dialog.avatar.actions.unblock') }}</el-dropdown-item variant="destructive"
> @click="avatarDialogCommand('Unblock Avatar')">
<el-dropdown-item v-else :icon="CircleClose" command="Block Avatar" divided>{{ <CircleCheck class="size-4" />
t('dialog.avatar.actions.block') {{ t('dialog.avatar.actions.unblock') }}
}}</el-dropdown-item> </DropdownMenuItem>
<el-dropdown-item <DropdownMenuItem v-else @click="avatarDialogCommand('Block Avatar')">
v-if="/quest/.test(avatarDialog.ref.tags)" <CircleClose class="size-4" />
:icon="Check" {{ t('dialog.avatar.actions.block') }}
command="Select Fallback Avatar" </DropdownMenuItem>
>{{ t('dialog.avatar.actions.select_fallback') }}</el-dropdown-item <DropdownMenuItem
> v-if="/quest/.test(avatarDialog.ref.tags)"
<template v-if="avatarDialog.ref.authorId === currentUser.id"> @click="avatarDialogCommand('Select Fallback Avatar')">
<el-dropdown-item <Check class="size-4" />
v-if="avatarDialog.ref.releaseStatus === 'public'" {{ t('dialog.avatar.actions.select_fallback') }}
:icon="User" </DropdownMenuItem>
command="Make Private" <template v-if="avatarDialog.ref.authorId === currentUser.id">
divided <DropdownMenuSeparator />
>{{ t('dialog.avatar.actions.make_private') }}</el-dropdown-item <DropdownMenuItem
> v-if="avatarDialog.ref.releaseStatus === 'public'"
<el-dropdown-item v-else :icon="User" command="Make Public" divided>{{ @click="avatarDialogCommand('Make Private')">
t('dialog.avatar.actions.make_public') <User class="size-4" />
}}</el-dropdown-item> {{ t('dialog.avatar.actions.make_private') }}
<el-dropdown-item :icon="Edit" command="Rename">{{ </DropdownMenuItem>
t('dialog.avatar.actions.rename') <DropdownMenuItem v-else @click="avatarDialogCommand('Make Public')">
}}</el-dropdown-item> <User class="size-4" />
<el-dropdown-item :icon="Edit" command="Change Description">{{ {{ t('dialog.avatar.actions.make_public') }}
t('dialog.avatar.actions.change_description') </DropdownMenuItem>
}}</el-dropdown-item> <DropdownMenuItem @click="avatarDialogCommand('Rename')">
<el-dropdown-item :icon="Edit" command="Change Content Tags">{{ <Edit class="size-4" />
t('dialog.avatar.actions.change_content_tags') {{ t('dialog.avatar.actions.rename') }}
}}</el-dropdown-item> </DropdownMenuItem>
<el-dropdown-item :icon="Edit" command="Change Styles and Author Tags">{{ <DropdownMenuItem @click="avatarDialogCommand('Change Description')">
t('dialog.avatar.actions.change_styles_author_tags') <Edit class="size-4" />
}}</el-dropdown-item> {{ t('dialog.avatar.actions.change_description') }}
<el-dropdown-item :icon="Picture" command="Change Image">{{ </DropdownMenuItem>
t('dialog.avatar.actions.change_image') <DropdownMenuItem @click="avatarDialogCommand('Change Content Tags')">
}}</el-dropdown-item> <Edit class="size-4" />
<el-dropdown-item {{ t('dialog.avatar.actions.change_content_tags') }}
v-if="avatarDialog.ref.unityPackageUrl" </DropdownMenuItem>
:icon="Download" <DropdownMenuItem @click="avatarDialogCommand('Change Styles and Author Tags')">
command="Download Unity Package" <Edit class="size-4" />
>{{ t('dialog.avatar.actions.download_package') }}</el-dropdown-item {{ t('dialog.avatar.actions.change_styles_author_tags') }}
> </DropdownMenuItem>
<el-dropdown-item <DropdownMenuItem @click="avatarDialogCommand('Change Image')">
v-if="avatarDialog.hasImposter" <Picture class="size-4" />
:icon="Refresh" {{ t('dialog.avatar.actions.change_image') }}
command="Regenerate Imposter" </DropdownMenuItem>
style="color: #f56c6c" <DropdownMenuItem
divided v-if="avatarDialog.ref.unityPackageUrl"
>{{ t('dialog.avatar.actions.regenerate_impostor') }}</el-dropdown-item @click="avatarDialogCommand('Download Unity Package')">
> <Download class="size-4" />
<el-dropdown-item {{ t('dialog.avatar.actions.download_package') }}
v-if="avatarDialog.hasImposter" </DropdownMenuItem>
:icon="Delete" <DropdownMenuSeparator />
command="Delete Imposter" <DropdownMenuItem
style="color: #f56c6c" v-if="avatarDialog.hasImposter"
>{{ t('dialog.avatar.actions.delete_impostor') }}</el-dropdown-item variant="destructive"
> @click="avatarDialogCommand('Regenerate Imposter')">
<el-dropdown-item v-else :icon="User" command="Create Imposter" divided>{{ <Refresh class="size-4" />
t('dialog.avatar.actions.create_impostor') {{ t('dialog.avatar.actions.regenerate_impostor') }}
}}</el-dropdown-item> </DropdownMenuItem>
<el-dropdown-item :icon="Delete" command="Delete" style="color: #f56c6c">{{ <DropdownMenuItem
t('dialog.avatar.actions.delete') v-if="avatarDialog.hasImposter"
}}</el-dropdown-item> variant="destructive"
</template> @click="avatarDialogCommand('Delete Imposter')">
</el-dropdown-menu> <Delete class="size-4" />
</template> {{ t('dialog.avatar.actions.delete_impostor') }}
</el-dropdown> </DropdownMenuItem>
<DropdownMenuItem v-else @click="avatarDialogCommand('Create Imposter')">
<User class="size-4" />
{{ t('dialog.avatar.actions.create_impostor') }}
</DropdownMenuItem>
<DropdownMenuItem variant="destructive" @click="avatarDialogCommand('Delete')">
<Delete class="size-4" />
{{ t('dialog.avatar.actions.delete') }}
</DropdownMenuItem>
</template>
</DropdownMenuContent>
</DropdownMenu>
</div> </div>
</div> </div>
</div> </div>
@@ -428,24 +439,24 @@
<span class="extra" <span class="extra"
>{{ avatarDialog.id >{{ avatarDialog.id
}}<TooltipWrapper side="top" :content="t('dialog.avatar.info.id_tooltip')"> }}<TooltipWrapper side="top" :content="t('dialog.avatar.info.id_tooltip')">
<el-dropdown trigger="click" size="small" style="margin-left: 5px"> <DropdownMenu>
<el-button <DropdownMenuTrigger as-child>
type="default" <el-button
:icon="CopyDocument" type="default"
size="small" :icon="CopyDocument"
circle size="small"
@click.stop></el-button> circle
<template #dropdown> @click.stop></el-button>
<el-dropdown-menu> </DropdownMenuTrigger>
<el-dropdown-item @click="copyAvatarId(avatarDialog.id)">{{ <DropdownMenuContent>
t('dialog.avatar.info.copy_id') <DropdownMenuItem @click="copyAvatarId(avatarDialog.id)">
}}</el-dropdown-item> {{ t('dialog.avatar.info.copy_id') }}
<el-dropdown-item @click="copyAvatarUrl(avatarDialog.id)">{{ </DropdownMenuItem>
t('dialog.avatar.info.copy_url') <DropdownMenuItem @click="copyAvatarUrl(avatarDialog.id)">
}}</el-dropdown-item> {{ t('dialog.avatar.info.copy_url') }}
</el-dropdown-menu> </DropdownMenuItem>
</template> </DropdownMenuContent>
</el-dropdown> </DropdownMenu>
</TooltipWrapper></span </TooltipWrapper></span
> >
</div> </div>
@@ -566,7 +577,7 @@
User, User,
Warning Warning
} from '@element-plus/icons-vue'; } from '@element-plus/icons-vue';
import { computed, defineAsyncComponent, nextTick, reactive, ref, watch } from 'vue'; import { computed, defineAsyncComponent, nextTick, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner'; import { toast } from 'vue-sonner';
@@ -585,6 +596,13 @@
replaceVrcPackageUrl, replaceVrcPackageUrl,
timeToText timeToText
} from '../../../shared/utils'; } from '../../../shared/utils';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '../../ui/dropdown-menu';
import { useAvatarStore, useFavoriteStore, useGalleryStore, useGameStore, useUserStore } from '../../../stores'; import { useAvatarStore, useFavoriteStore, useGalleryStore, useGameStore, useUserStore } from '../../../stores';
import { avatarModerationRequest, avatarRequest, favoriteRequest, miscRequest } from '../../../api'; import { avatarModerationRequest, avatarRequest, favoriteRequest, miscRequest } from '../../../api';
import { AppDebug } from '../../../service/appConfig.js'; import { AppDebug } from '../../../service/appConfig.js';
+160 -142
View File
@@ -231,102 +231,108 @@
@click="joinGroup(groupDialog.id)"></el-button> @click="joinGroup(groupDialog.id)"></el-button>
</TooltipWrapper> </TooltipWrapper>
</template> </template>
<el-dropdown trigger="click" style="margin-left: 5px" @command="groupDialogCommand"> <DropdownMenu>
<el-button <DropdownMenuTrigger as-child>
:type="groupDialog.ref.membershipStatus === 'userblocked' ? 'danger' : 'default'" <el-button
:icon="MoreFilled" :type="groupDialog.ref.membershipStatus === 'userblocked' ? 'danger' : 'default'"
size="large" :icon="MoreFilled"
circle></el-button> size="large"
<template #dropdown> class="ml-1.25"
<el-dropdown-menu> circle></el-button>
<el-dropdown-item :icon="Refresh" command="Refresh"> </DropdownMenuTrigger>
{{ t('dialog.group.actions.refresh') }} <DropdownMenuContent>
</el-dropdown-item> <DropdownMenuItem @click="groupDialogCommand('Refresh')">
<el-dropdown-item :icon="Share" command="Share"> <Refresh class="size-4" />
{{ t('dialog.group.actions.share') }} {{ t('dialog.group.actions.refresh') }}
</el-dropdown-item> </DropdownMenuItem>
<template v-if="groupDialog.inGroup"> <DropdownMenuItem @click="groupDialogCommand('Share')">
<template v-if="groupDialog.ref.myMember"> <Share class="size-4" />
<el-dropdown-item {{ t('dialog.group.actions.share') }}
v-if="groupDialog.ref.myMember.isSubscribedToAnnouncements" </DropdownMenuItem>
:icon="MuteNotification" <template v-if="groupDialog.inGroup">
command="Unsubscribe To Announcements" <template v-if="groupDialog.ref.myMember">
divided> <DropdownMenuSeparator />
{{ t('dialog.group.actions.unsubscribe') }} <DropdownMenuItem
</el-dropdown-item> v-if="groupDialog.ref.myMember.isSubscribedToAnnouncements"
<el-dropdown-item @click="groupDialogCommand('Unsubscribe To Announcements')">
v-else <MuteNotification class="size-4" />
:icon="Bell" {{ t('dialog.group.actions.unsubscribe') }}
command="Subscribe To Announcements" </DropdownMenuItem>
divided> <DropdownMenuItem
{{ t('dialog.group.actions.subscribe') }} v-else
</el-dropdown-item> @click="groupDialogCommand('Subscribe To Announcements')">
<el-dropdown-item <Bell class="size-4" />
v-if="hasGroupPermission(groupDialog.ref, 'group-invites-manage')" {{ t('dialog.group.actions.subscribe') }}
:icon="Message" </DropdownMenuItem>
command="Invite To Group"> <DropdownMenuItem
{{ t('dialog.group.actions.invite_to_group') }} v-if="hasGroupPermission(groupDialog.ref, 'group-invites-manage')"
</el-dropdown-item> @click="groupDialogCommand('Invite To Group')">
<template <Message class="size-4" />
v-if="hasGroupPermission(groupDialog.ref, 'group-announcement-manage')"> {{ t('dialog.group.actions.invite_to_group') }}
<el-dropdown-item :icon="Tickets" command="Create Post"> </DropdownMenuItem>
{{ t('dialog.group.actions.create_post') }} <template
</el-dropdown-item> v-if="hasGroupPermission(groupDialog.ref, 'group-announcement-manage')">
</template> <DropdownMenuItem @click="groupDialogCommand('Create Post')">
<el-dropdown-item <Tickets class="size-4" />
:disabled="!hasGroupModerationPermission(groupDialog.ref)" {{ t('dialog.group.actions.create_post') }}
:icon="Operation" </DropdownMenuItem>
command="Moderation Tools">
{{ t('dialog.group.actions.moderation_tools') }}
</el-dropdown-item>
<template
v-if="
groupDialog.ref.myMember && groupDialog.ref.privacy === 'default'
">
<el-dropdown-item :icon="View" command="Visibility Everyone" divided>
<el-icon v-if="groupDialog.ref.myMember.visibility === 'visible'"
><Check
/></el-icon>
{{ t('dialog.group.actions.visibility_everyone') }}
</el-dropdown-item>
<el-dropdown-item :icon="View" command="Visibility Friends">
<el-icon v-if="groupDialog.ref.myMember.visibility === 'friends'"
><Check
/></el-icon>
{{ t('dialog.group.actions.visibility_friends') }}
</el-dropdown-item>
<el-dropdown-item :icon="View" command="Visibility Hidden">
<el-icon v-if="groupDialog.ref.myMember.visibility === 'hidden'"
><Check
/></el-icon>
{{ t('dialog.group.actions.visibility_hidden') }}
</el-dropdown-item>
</template>
<el-dropdown-item
:icon="Delete"
command="Leave Group"
style="color: #f56c6c"
divided>
{{ t('dialog.group.actions.leave') }}
</el-dropdown-item>
</template> </template>
<DropdownMenuItem
:disabled="!hasGroupModerationPermission(groupDialog.ref)"
@click="groupDialogCommand('Moderation Tools')">
<Operation class="size-4" />
{{ t('dialog.group.actions.moderation_tools') }}
</DropdownMenuItem>
<template
v-if="groupDialog.ref.myMember && groupDialog.ref.privacy === 'default'">
<DropdownMenuSeparator />
<DropdownMenuItem @click="groupDialogCommand('Visibility Everyone')">
<View class="size-4" />
<Check
v-if="groupDialog.ref.myMember.visibility === 'visible'"
class="size-4" />
{{ t('dialog.group.actions.visibility_everyone') }}
</DropdownMenuItem>
<DropdownMenuItem @click="groupDialogCommand('Visibility Friends')">
<View class="size-4" />
<Check
v-if="groupDialog.ref.myMember.visibility === 'friends'"
class="size-4" />
{{ t('dialog.group.actions.visibility_friends') }}
</DropdownMenuItem>
<DropdownMenuItem @click="groupDialogCommand('Visibility Hidden')">
<View class="size-4" />
<Check
v-if="groupDialog.ref.myMember.visibility === 'hidden'"
class="size-4" />
{{ t('dialog.group.actions.visibility_hidden') }}
</DropdownMenuItem>
</template>
<DropdownMenuSeparator />
<DropdownMenuItem
variant="destructive"
@click="groupDialogCommand('Leave Group')">
<Delete class="size-4" />
{{ t('dialog.group.actions.leave') }}
</DropdownMenuItem>
</template> </template>
<template v-else> </template>
<el-dropdown-item <template v-else>
v-if="groupDialog.ref.membershipStatus === 'userblocked'" <DropdownMenuSeparator />
:icon="CircleCheck" <DropdownMenuItem
command="Unblock Group" v-if="groupDialog.ref.membershipStatus === 'userblocked'"
style="color: #f56c6c" variant="destructive"
divided> @click="groupDialogCommand('Unblock Group')">
{{ t('dialog.group.actions.unblock') }} <CircleCheck class="size-4" />
</el-dropdown-item> {{ t('dialog.group.actions.unblock') }}
<el-dropdown-item v-else :icon="CircleClose" command="Block Group" divided> </DropdownMenuItem>
{{ t('dialog.group.actions.block') }} <DropdownMenuItem v-else @click="groupDialogCommand('Block Group')">
</el-dropdown-item> <CircleClose class="size-4" />
</template> {{ t('dialog.group.actions.block') }}
</el-dropdown-menu> </DropdownMenuItem>
</template> </template>
</el-dropdown> </DropdownMenuContent>
</DropdownMenu>
</div> </div>
</div> </div>
</div> </div>
@@ -852,55 +858,60 @@
v-if="hasGroupPermission(groupDialog.ref, 'group-members-manage')" v-if="hasGroupPermission(groupDialog.ref, 'group-members-manage')"
style="float: right"> style="float: right">
<span style="margin-right: 5px">{{ t('dialog.group.members.sort_by') }}</span> <span style="margin-right: 5px">{{ t('dialog.group.members.sort_by') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger
size="small" as-child
style="margin-right: 5px" :disabled="isGroupMembersLoading || groupDialog.memberSearch.length > 0">
:disabled="isGroupMembersLoading || groupDialog.memberSearch.length > 0"> <el-button
<el-button size="small" @click.stop> size="small"
<span :disabled="isGroupMembersLoading || groupDialog.memberSearch.length > 0"
>{{ t(groupDialog.memberSortOrder.name) }} @click.stop>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon> <span>
</span> {{ t(groupDialog.memberSortOrder.name) }}
</el-button> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<template #dropdown> </span>
<el-dropdown-menu> </el-button>
<el-dropdown-item </DropdownMenuTrigger>
v-for="item in groupDialogSortingOptions" <DropdownMenuContent>
:key="item.name" <DropdownMenuItem
@click="setGroupMemberSortOrder(item)" v-for="item in groupDialogSortingOptions"
v-text="t(item.name)" /> :key="item.name"
</el-dropdown-menu> @click="setGroupMemberSortOrder(item)">
</template> {{ t(item.name) }}
</el-dropdown> </DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<span style="margin-right: 5px">{{ t('dialog.group.members.filter') }}</span> <span style="margin-right: 5px">{{ t('dialog.group.members.filter') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger
size="small" as-child
style="margin-right: 5px" :disabled="isGroupMembersLoading || groupDialog.memberSearch.length > 0">
:disabled="isGroupMembersLoading || groupDialog.memberSearch.length > 0"> <el-button
<el-button size="small" @click.stop> size="small"
<span :disabled="isGroupMembersLoading || groupDialog.memberSearch.length > 0"
>{{ t(groupDialog.memberFilter.name) }} @click.stop>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon <span>
></span> {{ t(groupDialog.memberFilter.name) }}
</el-button> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<template #dropdown> </span>
<el-dropdown-menu> </el-button>
<el-dropdown-item </DropdownMenuTrigger>
v-for="item in groupDialogFilterOptions" <DropdownMenuContent>
:key="item.name" <DropdownMenuItem
@click="setGroupMemberFilter(item)" v-for="item in groupDialogFilterOptions"
v-text="t(item.name)" /> :key="item.name"
<template v-for="role in groupDialog.ref.roles" :key="role.name"> @click="setGroupMemberFilter(item)">
<el-dropdown-item {{ t(item.name) }}
v-if="!role.defaultRole" </DropdownMenuItem>
@click="setGroupMemberFilter(role)" <template v-for="role in groupDialog.ref.roles" :key="role.name">
v-text="role.name" /> <DropdownMenuItem
</template> v-if="!role.defaultRole"
</el-dropdown-menu> @click="setGroupMemberFilter(role)">
</template> {{ role.name }}
</el-dropdown> </DropdownMenuItem>
</template>
</DropdownMenuContent>
</DropdownMenu>
</div> </div>
<el-input <el-input
v-model="groupDialog.memberSearch" v-model="groupDialog.memberSearch"
@@ -1176,6 +1187,13 @@
userImage, userImage,
userStatusClass userStatusClass
} from '../../../shared/utils'; } from '../../../shared/utils';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '../../ui/dropdown-menu';
import { useGalleryStore, useGroupStore, useLocationStore, useUserStore } from '../../../stores'; import { useGalleryStore, useGroupStore, useLocationStore, useUserStore } from '../../../stores';
import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants'; import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants';
import { Badge } from '../../ui/badge'; import { Badge } from '../../ui/badge';
@@ -24,69 +24,82 @@
</span> </span>
<div style="float: right; margin-top: 5px"> <div style="float: right; margin-top: 5px">
<span style="margin-right: 5px">{{ t('dialog.group.members.sort_by') }}</span> <span style="margin-right: 5px">{{ t('dialog.group.members.sort_by') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger
size="small" as-child
style="margin-right: 5px" :disabled="
:disabled=" Boolean(
Boolean( isGroupMembersLoading ||
isGroupMembersLoading || memberSearch.length ||
memberSearch.length || !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage')
!hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage') )
) ">
"> <el-button
<el-button size="small" @click.stop> size="small"
<span :disabled="
>{{ t(memberSortOrder.name) }} Boolean(
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon> isGroupMembersLoading ||
</span> memberSearch.length ||
</el-button> !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage')
<template #dropdown> )
<el-dropdown-menu> "
<el-dropdown-item @click.stop>
v-for="item in groupDialogSortingOptions" <span>
:key="item.name" {{ t(memberSortOrder.name) }}
@click="setGroupMemberSortOrder(item)"> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
{{ t(item.name) }} </span>
</el-dropdown-item> </el-button>
</el-dropdown-menu> </DropdownMenuTrigger>
</template> <DropdownMenuContent>
</el-dropdown> <DropdownMenuItem
v-for="item in groupDialogSortingOptions"
:key="item.name"
@click="setGroupMemberSortOrder(item)">
{{ t(item.name) }}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<span style="margin-right: 5px">{{ t('dialog.group.members.filter') }}</span> <span style="margin-right: 5px">{{ t('dialog.group.members.filter') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger
size="small" as-child
style="margin-right: 5px" :disabled="
:disabled=" Boolean(
Boolean( isGroupMembersLoading ||
isGroupMembersLoading || memberSearch.length ||
memberSearch.length || !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage')
!hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage') )
) ">
"> <el-button
<el-button size="small" @click.stop> size="small"
<span :disabled="
>{{ t(memberFilter.name) }} Boolean(
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon isGroupMembersLoading ||
></span> memberSearch.length ||
</el-button> !hasGroupPermission(groupMemberModeration.groupRef, 'group-bans-manage')
<template #dropdown> )
<el-dropdown-menu> "
<el-dropdown-item @click.stop>
v-for="item in groupDialogFilterOptions" <span>
:key="item.name" {{ t(memberFilter.name) }}
@click="setGroupMemberFilter(item)" <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
v-text="t(item.name)"></el-dropdown-item> </span>
<template v-for="role in groupMemberModeration.groupRef.roles" :key="role.name"> </el-button>
<el-dropdown-item </DropdownMenuTrigger>
v-if="!role.defaultRole" <DropdownMenuContent>
@click="setGroupMemberFilter(role)"> <DropdownMenuItem
{{ t(role.name) }} v-for="item in groupDialogFilterOptions"
</el-dropdown-item> :key="item.name"
</template> @click="setGroupMemberFilter(item)">
</el-dropdown-menu> {{ t(item.name) }}
</template> </DropdownMenuItem>
</el-dropdown> <template v-for="role in groupMemberModeration.groupRef.roles" :key="role.name">
<DropdownMenuItem v-if="!role.defaultRole" @click="setGroupMemberFilter(role)">
{{ t(role.name) }}
</DropdownMenuItem>
</template>
</DropdownMenuContent>
</DropdownMenu>
</div> </div>
<el-input <el-input
v-model="memberSearch" v-model="memberSearch"
@@ -869,6 +882,7 @@
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { debounce, formatDateFilter, hasGroupPermission, userImage, userImageFull } from '../../../shared/utils'; import { debounce, formatDateFilter, hasGroupPermission, userImage, userImageFull } from '../../../shared/utils';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '../../ui/dropdown-menu';
import { useAppearanceSettingsStore, useGalleryStore, useGroupStore, useUserStore } from '../../../stores'; import { useAppearanceSettingsStore, useGalleryStore, useGroupStore, useUserStore } from '../../../stores';
import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants'; import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants';
import { groupRequest, userRequest } from '../../../api'; import { groupRequest, userRequest } from '../../../api';
@@ -21,186 +21,212 @@
@click="userDialogCommand('Add Favorite')"></el-button> @click="userDialogCommand('Add Favorite')"></el-button>
</TooltipWrapper> </TooltipWrapper>
</template> </template>
<el-dropdown trigger="click" @command="onCommand"> <DropdownMenu>
<el-button <DropdownMenuTrigger as-child>
:type=" <el-button
userDialog.incomingRequest || userDialog.outgoingRequest :type="
? 'success' userDialog.incomingRequest || userDialog.outgoingRequest
: userDialog.isBlock || userDialog.isMute ? 'success'
? 'danger' : userDialog.isBlock || userDialog.isMute
: 'default' ? 'danger'
" : 'default'
:icon="MoreFilled" "
size="large" :icon="MoreFilled"
circle size="large"
style="margin-left: 5px"></el-button> circle
<template #dropdown> style="margin-left: 5px"></el-button>
<el-dropdown-menu> </DropdownMenuTrigger>
<el-dropdown-item :icon="Refresh" command="Refresh">{{ <DropdownMenuContent>
t('dialog.user.actions.refresh') <DropdownMenuItem @click="onCommand('Refresh')">
}}</el-dropdown-item> <Refresh class="size-4" />
<el-dropdown-item :icon="Share" command="Share">{{ {{ t('dialog.user.actions.refresh') }}
t('dialog.user.actions.share') </DropdownMenuItem>
}}</el-dropdown-item> <DropdownMenuItem @click="onCommand('Share')">
<template v-if="userDialog.ref.id === currentUser.id"> <Share class="size-4" />
<el-dropdown-item :icon="UserFilled" command="Show Avatar Author">{{ {{ t('dialog.user.actions.share') }}
t('dialog.user.actions.show_avatar_author') </DropdownMenuItem>
}}</el-dropdown-item> <template v-if="userDialog.ref.id === currentUser.id">
<el-dropdown-item :icon="UserFilled" command="Show Fallback Avatar Details">{{ <DropdownMenuItem @click="onCommand('Show Avatar Author')">
t('dialog.user.actions.show_fallback_avatar') <UserFilled class="size-4" />
}}</el-dropdown-item> {{ t('dialog.user.actions.show_avatar_author') }}
<el-dropdown-item :icon="Edit" command="Edit Social Status" divided>{{ </DropdownMenuItem>
t('dialog.user.actions.edit_status') <DropdownMenuItem @click="onCommand('Show Fallback Avatar Details')">
}}</el-dropdown-item> <UserFilled class="size-4" />
<el-dropdown-item :icon="Edit" command="Edit Language">{{ {{ t('dialog.user.actions.show_fallback_avatar') }}
t('dialog.user.actions.edit_language') </DropdownMenuItem>
}}</el-dropdown-item> <DropdownMenuSeparator />
<el-dropdown-item :icon="Edit" command="Edit Bio">{{ <DropdownMenuItem @click="onCommand('Edit Social Status')">
t('dialog.user.actions.edit_bio') <Edit class="size-4" />
}}</el-dropdown-item> {{ t('dialog.user.actions.edit_status') }}
<el-dropdown-item :icon="Edit" command="Edit Pronouns">{{ </DropdownMenuItem>
t('dialog.user.actions.edit_pronouns') <DropdownMenuItem @click="onCommand('Edit Language')">
}}</el-dropdown-item> <Edit class="size-4" />
<el-dropdown-item :icon="SwitchButton" command="Logout" divided>{{ {{ t('dialog.user.actions.edit_language') }}
t('dialog.user.actions.logout') </DropdownMenuItem>
}}</el-dropdown-item> <DropdownMenuItem @click="onCommand('Edit Bio')">
<Edit class="size-4" />
{{ t('dialog.user.actions.edit_bio') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Edit Pronouns')">
<Edit class="size-4" />
{{ t('dialog.user.actions.edit_pronouns') }}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem @click="onCommand('Logout')">
<SwitchButton class="size-4" />
{{ t('dialog.user.actions.logout') }}
</DropdownMenuItem>
</template>
<template v-else>
<template v-if="userDialog.isFriend">
<DropdownMenuSeparator />
<DropdownMenuItem @click="onCommand('Request Invite')">
<Postcard class="size-4" />
{{ t('dialog.user.actions.request_invite') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Request Invite Message')">
<Postcard class="size-4" />
{{ t('dialog.user.actions.request_invite_with_message') }}
</DropdownMenuItem>
<template v-if="isGameRunning">
<DropdownMenuItem
:disabled="!checkCanInvite(lastLocation.location)"
@click="onCommand('Invite')">
<Message class="size-4" />
{{ t('dialog.user.actions.invite') }}
</DropdownMenuItem>
<DropdownMenuItem
:disabled="!checkCanInvite(lastLocation.location)"
@click="onCommand('Invite Message')">
<Message class="size-4" />
{{ t('dialog.user.actions.invite_with_message') }}
</DropdownMenuItem>
</template>
<DropdownMenuItem :disabled="!currentUser.isBoopingEnabled" @click="onCommand('Send Boop')">
<Pointer class="size-4" />
{{ t('dialog.user.actions.send_boop') }}
</DropdownMenuItem>
</template> </template>
<template v-else> <template v-else-if="userDialog.incomingRequest">
<template v-if="userDialog.isFriend"> <DropdownMenuItem @click="onCommand('Accept Friend Request')">
<el-dropdown-item :icon="Postcard" command="Request Invite" divided>{{ <Check class="size-4" />
t('dialog.user.actions.request_invite') {{ t('dialog.user.actions.accept_friend_request') }}
}}</el-dropdown-item> </DropdownMenuItem>
<el-dropdown-item :icon="Postcard" command="Request Invite Message">{{ <DropdownMenuItem @click="onCommand('Decline Friend Request')">
t('dialog.user.actions.request_invite_with_message') <Close class="size-4" />
}}</el-dropdown-item> {{ t('dialog.user.actions.decline_friend_request') }}
<template v-if="isGameRunning"> </DropdownMenuItem>
<el-dropdown-item
:disabled="!checkCanInvite(lastLocation.location)"
:icon="Message"
command="Invite"
>{{ t('dialog.user.actions.invite') }}</el-dropdown-item
>
<el-dropdown-item
:disabled="!checkCanInvite(lastLocation.location)"
:icon="Message"
command="Invite Message"
>{{ t('dialog.user.actions.invite_with_message') }}</el-dropdown-item
>
</template>
<el-dropdown-item
:disabled="!currentUser.isBoopingEnabled"
:icon="Pointer"
command="Send Boop"
>{{ t('dialog.user.actions.send_boop') }}</el-dropdown-item
>
</template>
<template v-else-if="userDialog.incomingRequest">
<el-dropdown-item :icon="Check" command="Accept Friend Request">{{
t('dialog.user.actions.accept_friend_request')
}}</el-dropdown-item>
<el-dropdown-item :icon="Close" command="Decline Friend Request">{{
t('dialog.user.actions.decline_friend_request')
}}</el-dropdown-item>
</template>
<el-dropdown-item
v-else-if="userDialog.outgoingRequest"
:icon="Close"
command="Cancel Friend Request">
{{ t('dialog.user.actions.cancel_friend_request') }}
</el-dropdown-item>
<el-dropdown-item v-else :icon="Plus" command="Send Friend Request">{{
t('dialog.user.actions.send_friend_request')
}}</el-dropdown-item>
<el-dropdown-item :icon="Message" command="Invite To Group">{{
t('dialog.user.actions.invite_to_group')
}}</el-dropdown-item>
<el-dropdown-item :icon="Operation" command="Group Moderation">{{
t('dialog.user.actions.group_moderation')
}}</el-dropdown-item>
<el-dropdown-item :icon="Edit" command="Edit Note Memo"> Edit Note and Memo </el-dropdown-item>
<el-dropdown-item :icon="UserFilled" command="Show Avatar Author" divided>{{
t('dialog.user.actions.show_avatar_author')
}}</el-dropdown-item>
<el-dropdown-item :icon="UserFilled" command="Show Fallback Avatar Details">{{
t('dialog.user.actions.show_fallback_avatar')
}}</el-dropdown-item>
<el-dropdown-item :icon="DataLine" command="Previous Instances">{{
t('dialog.user.actions.show_previous_instances')
}}</el-dropdown-item>
<el-dropdown-item
v-if="userDialog.isBlock"
:icon="CircleCheck"
command="Moderation Unblock"
divided
style="color: var(--el-color-danger)">
{{ t('dialog.user.actions.moderation_unblock') }}
</el-dropdown-item>
<el-dropdown-item
v-else
:icon="CircleClose"
command="Moderation Block"
divided
:disabled="userDialog.ref.$isModerator">
{{ t('dialog.user.actions.moderation_block') }}
</el-dropdown-item>
<el-dropdown-item
v-if="userDialog.isMute"
:icon="Microphone"
command="Moderation Unmute"
style="color: var(--el-color-danger)">
{{ t('dialog.user.actions.moderation_unmute') }}
</el-dropdown-item>
<el-dropdown-item
v-else
:icon="Mute"
command="Moderation Mute"
:disabled="userDialog.ref.$isModerator">
{{ t('dialog.user.actions.moderation_mute') }}
</el-dropdown-item>
<el-dropdown-item
v-if="userDialog.isMuteChat"
:icon="ChatLineRound"
command="Moderation Enable Chatbox"
style="color: var(--el-color-danger)">
{{ t('dialog.user.actions.moderation_enable_chatbox') }}
</el-dropdown-item>
<el-dropdown-item v-else :icon="ChatDotRound" command="Moderation Disable Chatbox">
{{ t('dialog.user.actions.moderation_disable_chatbox') }}
</el-dropdown-item>
<el-dropdown-item :icon="User" command="Show Avatar">
<el-icon v-if="userDialog.isShowAvatar" style="margin-right: 5px"><Check /></el-icon>
<span>{{ t('dialog.user.actions.moderation_show_avatar') }}</span>
</el-dropdown-item>
<el-dropdown-item :icon="User" command="Hide Avatar">
<el-icon v-if="userDialog.isHideAvatar" style="margin-right: 5px"><Check /></el-icon>
<span>{{ t('dialog.user.actions.moderation_hide_avatar') }}</span>
</el-dropdown-item>
<el-dropdown-item
v-if="userDialog.isInteractOff"
:icon="Pointer"
command="Moderation Enable Avatar Interaction"
style="color: var(--el-color-danger)">
{{ t('dialog.user.actions.moderation_enable_avatar_interaction') }}
</el-dropdown-item>
<el-dropdown-item v-else :icon="CircleClose" command="Moderation Disable Avatar Interaction">
{{ t('dialog.user.actions.moderation_disable_avatar_interaction') }}
</el-dropdown-item>
<el-dropdown-item :icon="Flag" command="Report Hacking" :disabled="userDialog.ref.$isModerator">
{{ t('dialog.user.actions.report_hacking') }}
</el-dropdown-item>
<template v-if="userDialog.isFriend">
<el-dropdown-item
:icon="Delete"
command="Unfriend"
divided
style="color: var(--el-color-danger)">
{{ t('dialog.user.actions.unfriend') }}
</el-dropdown-item>
</template>
</template> </template>
</el-dropdown-menu> <DropdownMenuItem
</template> v-else-if="userDialog.outgoingRequest"
</el-dropdown> @click="onCommand('Cancel Friend Request')">
<Close class="size-4" />
{{ t('dialog.user.actions.cancel_friend_request') }}
</DropdownMenuItem>
<DropdownMenuItem v-else @click="onCommand('Send Friend Request')">
<Plus class="size-4" />
{{ t('dialog.user.actions.send_friend_request') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Invite To Group')">
<Message class="size-4" />
{{ t('dialog.user.actions.invite_to_group') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Group Moderation')">
<Operation class="size-4" />
{{ t('dialog.user.actions.group_moderation') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Edit Note Memo')">
<Edit class="size-4" />
Edit Note and Memo
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem @click="onCommand('Show Avatar Author')">
<UserFilled class="size-4" />
{{ t('dialog.user.actions.show_avatar_author') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Show Fallback Avatar Details')">
<UserFilled class="size-4" />
{{ t('dialog.user.actions.show_fallback_avatar') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Previous Instances')">
<DataLine class="size-4" />
{{ t('dialog.user.actions.show_previous_instances') }}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
v-if="userDialog.isBlock"
variant="destructive"
@click="onCommand('Moderation Unblock')">
<CircleCheck class="size-4" />
{{ t('dialog.user.actions.moderation_unblock') }}
</DropdownMenuItem>
<DropdownMenuItem
v-else
:disabled="userDialog.ref.$isModerator"
@click="onCommand('Moderation Block')">
<CircleClose class="size-4" />
{{ t('dialog.user.actions.moderation_block') }}
</DropdownMenuItem>
<DropdownMenuItem
v-if="userDialog.isMute"
variant="destructive"
@click="onCommand('Moderation Unmute')">
<Microphone class="size-4" />
{{ t('dialog.user.actions.moderation_unmute') }}
</DropdownMenuItem>
<DropdownMenuItem
v-else
:disabled="userDialog.ref.$isModerator"
@click="onCommand('Moderation Mute')">
<Mute class="size-4" />
{{ t('dialog.user.actions.moderation_mute') }}
</DropdownMenuItem>
<DropdownMenuItem
v-if="userDialog.isMuteChat"
variant="destructive"
@click="onCommand('Moderation Enable Chatbox')">
<ChatLineRound class="size-4" />
{{ t('dialog.user.actions.moderation_enable_chatbox') }}
</DropdownMenuItem>
<DropdownMenuItem v-else @click="onCommand('Moderation Disable Chatbox')">
<ChatDotRound class="size-4" />
{{ t('dialog.user.actions.moderation_disable_chatbox') }}
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Show Avatar')">
<User class="size-4" />
<Check v-if="userDialog.isShowAvatar" class="size-4" />
<span>{{ t('dialog.user.actions.moderation_show_avatar') }}</span>
</DropdownMenuItem>
<DropdownMenuItem @click="onCommand('Hide Avatar')">
<User class="size-4" />
<Check v-if="userDialog.isHideAvatar" class="size-4" />
<span>{{ t('dialog.user.actions.moderation_hide_avatar') }}</span>
</DropdownMenuItem>
<DropdownMenuItem
v-if="userDialog.isInteractOff"
variant="destructive"
@click="onCommand('Moderation Enable Avatar Interaction')">
<Pointer class="size-4" />
{{ t('dialog.user.actions.moderation_enable_avatar_interaction') }}
</DropdownMenuItem>
<DropdownMenuItem v-else @click="onCommand('Moderation Disable Avatar Interaction')">
<CircleClose class="size-4" />
{{ t('dialog.user.actions.moderation_disable_avatar_interaction') }}
</DropdownMenuItem>
<DropdownMenuItem :disabled="userDialog.ref.$isModerator" @click="onCommand('Report Hacking')">
<Flag class="size-4" />
{{ t('dialog.user.actions.report_hacking') }}
</DropdownMenuItem>
<template v-if="userDialog.isFriend">
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive" @click="onCommand('Unfriend')">
<Delete class="size-4" />
{{ t('dialog.user.actions.unfriend') }}
</DropdownMenuItem>
</template>
</template>
</DropdownMenuContent>
</DropdownMenu>
</div> </div>
</template> </template>
@@ -236,6 +262,13 @@
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '../../ui/dropdown-menu';
import { useGameStore, useLocationStore, useUserStore } from '../../../stores'; import { useGameStore, useLocationStore, useUserStore } from '../../../stores';
import { checkCanInvite } from '../../../shared/utils'; import { checkCanInvite } from '../../../shared/utils';
+207 -235
View File
@@ -512,27 +512,28 @@
<span class="extra"> <span class="extra">
{{ userDialog.id }} {{ userDialog.id }}
<TooltipWrapper side="top" :content="t('dialog.user.info.id_tooltip')"> <TooltipWrapper side="top" :content="t('dialog.user.info.id_tooltip')">
<el-dropdown trigger="click" size="small" style="margin-left: 5px" @click.stop> <DropdownMenu>
<el-button <DropdownMenuTrigger as-child>
type="default" <el-button
:icon="CopyDocument" type="default"
size="small" :icon="CopyDocument"
circle></el-button> size="small"
<template #dropdown> circle
<el-dropdown-menu> @click.stop></el-button>
<el-dropdown-item @click="copyUserId(userDialog.id)">{{ </DropdownMenuTrigger>
t('dialog.user.info.copy_id') <DropdownMenuContent>
}}</el-dropdown-item> <DropdownMenuItem @click="copyUserId(userDialog.id)">
<el-dropdown-item @click="copyUserURL(userDialog.id)">{{ {{ t('dialog.user.info.copy_id') }}
t('dialog.user.info.copy_url') </DropdownMenuItem>
}}</el-dropdown-item> <DropdownMenuItem @click="copyUserURL(userDialog.id)">
<el-dropdown-item {{ t('dialog.user.info.copy_url') }}
@click="copyUserDisplayName(userDialog.ref.displayName)" </DropdownMenuItem>
>{{ t('dialog.user.info.copy_display_name') }}</el-dropdown-item <DropdownMenuItem
> @click="copyUserDisplayName(userDialog.ref.displayName)">
</el-dropdown-menu> {{ t('dialog.user.info.copy_display_name') }}
</template> </DropdownMenuItem>
</el-dropdown> </DropdownMenuContent>
</DropdownMenu>
</TooltipWrapper> </TooltipWrapper>
</span> </span>
</div> </div>
@@ -561,29 +562,24 @@
</div> </div>
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<span style="margin-right: 5px">{{ t('dialog.user.groups.sort_by') }}</span> <span style="margin-right: 5px">{{ t('dialog.user.groups.sort_by') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger as-child :disabled="userDialog.isMutualFriendsLoading">
size="small" <el-button size="small" :disabled="userDialog.isMutualFriendsLoading" @click.stop>
style="margin-right: 5px" <span>
:disabled="userDialog.isMutualFriendsLoading" {{ t(userDialog.mutualFriendSorting.name) }}
@click.stop> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<el-button size="small"> </span>
<span </el-button>
>{{ t(userDialog.mutualFriendSorting.name) }} </DropdownMenuTrigger>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon> <DropdownMenuContent>
</span> <DropdownMenuItem
</el-button> v-for="(item, key) in userDialogMutualFriendSortingOptions"
<template #dropdown> :key="key"
<el-dropdown-menu> @click="setUserDialogMutualFriendSorting(item)">
<el-dropdown-item {{ t(item.name) }}
v-for="(item, key) in userDialogMutualFriendSortingOptions" </DropdownMenuItem>
:key="key" </DropdownMenuContent>
@click="setUserDialogMutualFriendSorting(item)" </DropdownMenu>
>{{ t(item.name) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div> </div>
</div> </div>
<div <div
@@ -645,33 +641,28 @@
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<template v-if="!userDialogGroupEditMode"> <template v-if="!userDialogGroupEditMode">
<span style="margin-right: 5px">{{ t('dialog.user.groups.sort_by') }}</span> <span style="margin-right: 5px">{{ t('dialog.user.groups.sort_by') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger as-child :disabled="userDialog.isGroupsLoading">
size="small" <el-button size="small" :disabled="userDialog.isGroupsLoading" @click.stop>
style="margin-right: 5px" <span>
:disabled="userDialog.isGroupsLoading" {{ t(userDialog.groupSorting.name) }}
@click.stop> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<el-button size="small"> </span>
<span </el-button>
>{{ t(userDialog.groupSorting.name) }} </DropdownMenuTrigger>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon> <DropdownMenuContent>
</span> <DropdownMenuItem
</el-button> v-for="(item, key) in userDialogGroupSortingOptions"
<template #dropdown> :key="key"
<el-dropdown-menu> :disabled="
<el-dropdown-item item === userDialogGroupSortingOptions.inGame &&
v-for="(item, key) in userDialogGroupSortingOptions" userDialog.id !== currentUser.id
:key="key" "
:disabled=" @click="setUserDialogGroupSorting(item)">
item === userDialogGroupSortingOptions.inGame && {{ t(item.name) }}
userDialog.id !== currentUser.id </DropdownMenuItem>
" </DropdownMenuContent>
@click="setUserDialogGroupSorting(item)" </DropdownMenu>
>{{ t(item.name) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template> </template>
<el-button <el-button
v-if="userDialogGroupEditMode" v-if="userDialogGroupEditMode"
@@ -695,32 +686,38 @@
<template v-if="userDialogGroupEditMode"> <template v-if="userDialogGroupEditMode">
<div class="x-friend-list" style="margin-top: 10px; margin-bottom: 15px; max-height: unset"> <div class="x-friend-list" style="margin-top: 10px; margin-bottom: 15px; max-height: unset">
<!-- Bulk actions dropdown (shown only in edit mode) --> <!-- Bulk actions dropdown (shown only in edit mode) -->
<el-dropdown trigger="click"> <DropdownMenu>
<el-button <DropdownMenuTrigger as-child>
size="small" <el-button
:icon="Setting" size="small"
style="margin-right: 5px; height: 29px; padding: 7px 15px; margin-bottom: 5px"> :icon="Setting"
{{ t('dialog.group.actions.manage_selected') }} style="
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon> margin-right: 5px;
</el-button> height: 29px;
<template #dropdown> padding: 7px 15px;
<el-dropdown-menu> margin-bottom: 5px;
<el-dropdown-item @click="bulkSetVisibility('visible')"> ">
{{ t('dialog.group.actions.visibility_everyone') }} {{ t('dialog.group.actions.manage_selected') }}
</el-dropdown-item> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<el-dropdown-item @click="bulkSetVisibility('friends')"> </el-button>
{{ t('dialog.group.actions.visibility_friends') }} </DropdownMenuTrigger>
</el-dropdown-item> <DropdownMenuContent>
<el-dropdown-item @click="bulkSetVisibility('hidden')"> <DropdownMenuItem @click="bulkSetVisibility('visible')">
{{ t('dialog.group.actions.visibility_hidden') }} {{ t('dialog.group.actions.visibility_everyone') }}
</el-dropdown-item> </DropdownMenuItem>
<el-dropdown-item divided @click="bulkLeaveGroups"> <DropdownMenuItem @click="bulkSetVisibility('friends')">
<el-icon><Delete /></el-icon> {{ t('dialog.group.actions.visibility_friends') }}
{{ t('dialog.user.groups.leave_group_tooltip') }} </DropdownMenuItem>
</el-dropdown-item> <DropdownMenuItem @click="bulkSetVisibility('hidden')">
</el-dropdown-menu> {{ t('dialog.group.actions.visibility_hidden') }}
</template> </DropdownMenuItem>
</el-dropdown> <DropdownMenuSeparator />
<DropdownMenuItem variant="destructive" @click="bulkLeaveGroups">
<Delete class="size-4" />
{{ t('dialog.user.groups.leave_group_tooltip') }}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<!-- Select All button --> <!-- Select All button -->
<el-button <el-button
@@ -813,49 +810,37 @@
<span>({{ group.memberCount }})</span> <span>({{ group.memberCount }})</span>
</span> </span>
</div> </div>
<el-dropdown <DropdownMenu v-if="group.myMember?.visibility">
v-if="group.myMember?.visibility" <DropdownMenuTrigger as-child :disabled="group.privacy !== 'default'">
trigger="click" <el-button :disabled="group.privacy !== 'default'" @click.stop size="small">
size="small" <span v-if="group.myMember.visibility === 'visible'">{{
style="margin-right: 5px"> t('dialog.group.tags.visible')
<el-button :disabled="group.privacy !== 'default'" @click.stop size="small"> }}</span>
<span v-if="group.myMember.visibility === 'visible'">{{ <span v-else-if="group.myMember.visibility === 'friends'">{{
t('dialog.group.tags.visible') t('dialog.group.tags.friends')
}}</span> }}</span>
<span v-else-if="group.myMember.visibility === 'friends'">{{ <span v-else-if="group.myMember.visibility === 'hidden'">{{
t('dialog.group.tags.friends') t('dialog.group.tags.hidden')
}}</span> }}</span>
<span v-else-if="group.myMember.visibility === 'hidden'">{{ <span v-else>{{ group.myMember.visibility }}</span>
t('dialog.group.tags.hidden') <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
}}</span> </el-button>
<span v-else>{{ group.myMember.visibility }}</span> </DropdownMenuTrigger>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon> <DropdownMenuContent>
</el-button> <DropdownMenuItem @click="setGroupVisibility(group.id, 'visible')">
<template #dropdown> <Check v-if="group.myMember.visibility === 'visible'" class="size-4" />
<el-dropdown-menu> {{ t('dialog.group.actions.visibility_everyone') }}
<el-dropdown-item @click="setGroupVisibility(group.id, 'visible')"> </DropdownMenuItem>
<el-icon v-if="group.myMember.visibility === 'visible'" <DropdownMenuItem @click="setGroupVisibility(group.id, 'friends')">
><Check <Check v-if="group.myMember.visibility === 'friends'" class="size-4" />
/></el-icon> {{ t('dialog.group.actions.visibility_friends') }}
{{ </DropdownMenuItem>
t('dialog.group.actions.visibility_everyone') <DropdownMenuItem @click="setGroupVisibility(group.id, 'hidden')">
}}</el-dropdown-item <Check v-if="group.myMember.visibility === 'hidden'" class="size-4" />
> {{ t('dialog.group.actions.visibility_hidden') }}
<el-dropdown-item @click="setGroupVisibility(group.id, 'friends')"> </DropdownMenuItem>
<el-icon v-if="group.myMember.visibility === 'friends'" </DropdownMenuContent>
><Check </DropdownMenu>
/></el-icon>
{{ t('dialog.group.actions.visibility_friends') }}</el-dropdown-item
>
<el-dropdown-item @click="setGroupVisibility(group.id, 'hidden')"
><el-icon v-if="group.myMember.visibility === 'hidden'"
><Check
/></el-icon>
{{ t('dialog.group.actions.visibility_hidden') }}</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
<!--//- JSON is missing isSubscribedToAnnouncements, can't be implemented--> <!--//- JSON is missing isSubscribedToAnnouncements, can't be implemented-->
<!-- <el-button <!-- <el-button
@click.stop=" @click.stop="
@@ -1052,53 +1037,43 @@
</div> </div>
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<span style="margin-right: 5px">{{ t('dialog.user.worlds.sort_by') }}</span> <span style="margin-right: 5px">{{ t('dialog.user.worlds.sort_by') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger as-child :disabled="userDialog.isWorldsLoading">
size="small" <el-button size="small" :disabled="userDialog.isWorldsLoading" @click.stop>
style="margin-right: 5px" <span>
:disabled="userDialog.isWorldsLoading" {{ t(userDialog.worldSorting.name) }}
@click.stop> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<el-button size="small"> </span>
<span </el-button>
>{{ t(userDialog.worldSorting.name) }} </DropdownMenuTrigger>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon <DropdownMenuContent>
></span> <DropdownMenuItem
</el-button> v-for="(item, key) in userDialogWorldSortingOptions"
<template #dropdown> :key="key"
<el-dropdown-menu> @click="setUserDialogWorldSorting(item)">
<el-dropdown-item {{ t(item.name) }}
v-for="(item, key) in userDialogWorldSortingOptions" </DropdownMenuItem>
:key="key" </DropdownMenuContent>
@click="setUserDialogWorldSorting(item)"> </DropdownMenu>
{{ t(item.name) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<span style="margin: 0 5px">{{ t('dialog.user.worlds.order_by') }}</span> <span style="margin: 0 5px">{{ t('dialog.user.worlds.order_by') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger as-child :disabled="userDialog.isWorldsLoading">
size="small" <el-button size="small" :disabled="userDialog.isWorldsLoading" @click.stop>
style="margin-right: 5px" <span>
:disabled="userDialog.isWorldsLoading" {{ t(userDialog.worldOrder.name) }}
@click.stop> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<el-button size="small"> </span>
<span </el-button>
>{{ t(userDialog.worldOrder.name) }} </DropdownMenuTrigger>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon <DropdownMenuContent>
></span> <DropdownMenuItem
</el-button> v-for="(item, key) in userDialogWorldOrderOptions"
<template #dropdown> :key="key"
<el-dropdown-menu> @click="setUserDialogWorldOrder(item)">
<el-dropdown-item {{ t(item.name) }}
v-for="(item, key) in userDialogWorldOrderOptions" </DropdownMenuItem>
:key="key" </DropdownMenuContent>
@click="setUserDialogWorldOrder(item)"> </DropdownMenu>
{{ t(item.name) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div> </div>
</div> </div>
<div <div
@@ -1214,58 +1189,48 @@
<div> <div>
<template v-if="userDialog.ref.id === currentUser.id"> <template v-if="userDialog.ref.id === currentUser.id">
<span style="margin-right: 5px">{{ t('dialog.user.avatars.sort_by') }}</span> <span style="margin-right: 5px">{{ t('dialog.user.avatars.sort_by') }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger as-child :disabled="userDialog.isWorldsLoading">
size="small" <el-button size="small" :disabled="userDialog.isWorldsLoading" @click.stop>
style="margin-right: 5px" <span>
:disabled="userDialog.isWorldsLoading" {{ t(`dialog.user.avatars.sort_by_${userDialog.avatarSorting}`) }}
@click.stop> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<el-button size="small"> </span>
<span </el-button>
>{{ t(`dialog.user.avatars.sort_by_${userDialog.avatarSorting}`) }} </DropdownMenuTrigger>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon <DropdownMenuContent>
></span> <DropdownMenuItem @click="changeUserDialogAvatarSorting('name')">
</el-button> {{ t('dialog.user.avatars.sort_by_name') }}
<template #dropdown> </DropdownMenuItem>
<el-dropdown-menu> <DropdownMenuItem @click="changeUserDialogAvatarSorting('update')">
<el-dropdown-item @click="changeUserDialogAvatarSorting('name')"> {{ t('dialog.user.avatars.sort_by_update') }}
{{ t('dialog.user.avatars.sort_by_name') }} </DropdownMenuItem>
</el-dropdown-item> </DropdownMenuContent>
<el-dropdown-item @click="changeUserDialogAvatarSorting('update')"> </DropdownMenu>
{{ t('dialog.user.avatars.sort_by_update') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<span style="margin-right: 5px; margin-left: 10px">{{ <span style="margin-right: 5px; margin-left: 10px">{{
t('dialog.user.avatars.group_by') t('dialog.user.avatars.group_by')
}}</span> }}</span>
<el-dropdown <DropdownMenu>
trigger="click" <DropdownMenuTrigger as-child :disabled="userDialog.isWorldsLoading">
size="small" <el-button size="small" :disabled="userDialog.isWorldsLoading" @click.stop>
style="margin-right: 5px" <span>
:disabled="userDialog.isWorldsLoading" {{ t(`dialog.user.avatars.${userDialog.avatarReleaseStatus}`) }}
@click.stop> <el-icon style="margin-left: 5px"><ArrowDown /></el-icon>
<el-button size="small"> </span>
<span </el-button>
>{{ t(`dialog.user.avatars.${userDialog.avatarReleaseStatus}`) }} </DropdownMenuTrigger>
<el-icon style="margin-left: 5px"><ArrowDown /></el-icon <DropdownMenuContent>
></span> <DropdownMenuItem @click="userDialog.avatarReleaseStatus = 'all'">
</el-button> {{ t('dialog.user.avatars.all') }}
<template #dropdown> </DropdownMenuItem>
<el-dropdown-menu> <DropdownMenuItem @click="userDialog.avatarReleaseStatus = 'public'">
<el-dropdown-item @click="userDialog.avatarReleaseStatus = 'all'"> {{ t('dialog.user.avatars.public') }}
{{ t('dialog.user.avatars.all') }} </DropdownMenuItem>
</el-dropdown-item> <DropdownMenuItem @click="userDialog.avatarReleaseStatus = 'private'">
<el-dropdown-item @click="userDialog.avatarReleaseStatus = 'public'"> {{ t('dialog.user.avatars.private') }}
{{ t('dialog.user.avatars.public') }} </DropdownMenuItem>
</el-dropdown-item> </DropdownMenuContent>
<el-dropdown-item @click="userDialog.avatarReleaseStatus = 'private'"> </DropdownMenu>
{{ t('dialog.user.avatars.private') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template> </template>
</div> </div>
</div> </div>
@@ -1412,6 +1377,13 @@
userRequest, userRequest,
worldRequest worldRequest
} from '../../../api'; } from '../../../api';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '../../ui/dropdown-menu';
import { processBulk, request } from '../../../service/request'; import { processBulk, request } from '../../../service/request';
import { userDialogGroupSortingOptions, userDialogMutualFriendSortingOptions } from '../../../shared/constants'; import { userDialogGroupSortingOptions, userDialogMutualFriendSortingOptions } from '../../../shared/constants';
import { userDialogWorldOrderOptions, userDialogWorldSortingOptions } from '../../../shared/constants/'; import { userDialogWorldOrderOptions, userDialogWorldSortingOptions } from '../../../shared/constants/';
+144 -118
View File
@@ -181,110 +181,124 @@
style="margin-left: 5px" style="margin-left: 5px"
@click="worldDialogCommand('Add Favorite')" /> @click="worldDialogCommand('Add Favorite')" />
</TooltipWrapper> </TooltipWrapper>
<el-dropdown trigger="click" style="margin-left: 5px" @command="worldDialogCommand"> <DropdownMenu>
<el-button type="default" :icon="MoreFilled" size="large" circle /> <DropdownMenuTrigger as-child>
<template #dropdown> <el-button type="default" :icon="MoreFilled" size="large" circle />
<el-dropdown-menu> </DropdownMenuTrigger>
<el-dropdown-item :icon="Refresh" command="Refresh"> <DropdownMenuContent>
{{ t('dialog.world.actions.refresh') }} <DropdownMenuItem @click="worldDialogCommand('Refresh')">
</el-dropdown-item> <Refresh class="size-4" />
<el-dropdown-item :icon="Share" command="Share"> {{ t('dialog.world.actions.refresh') }}
{{ t('dialog.world.actions.share') }} </DropdownMenuItem>
</el-dropdown-item> <DropdownMenuItem @click="worldDialogCommand('Share')">
<el-dropdown-item :icon="Flag" command="New Instance" divided> <Share class="size-4" />
{{ t('dialog.world.actions.new_instance') }} {{ t('dialog.world.actions.share') }}
</el-dropdown-item> </DropdownMenuItem>
<el-dropdown-item :icon="Message" command="New Instance and Self Invite"> <DropdownMenuSeparator />
{{ <DropdownMenuItem @click="worldDialogCommand('New Instance')">
canOpenInstanceInGame <Flag class="size-4" />
? t('dialog.world.actions.new_instance_and_open_ingame') {{ t('dialog.world.actions.new_instance') }}
: t('dialog.world.actions.new_instance_and_self_invite') </DropdownMenuItem>
}} <DropdownMenuItem @click="worldDialogCommand('New Instance and Self Invite')">
</el-dropdown-item> <Message class="size-4" />
<el-dropdown-item {{
canOpenInstanceInGame
? t('dialog.world.actions.new_instance_and_open_ingame')
: t('dialog.world.actions.new_instance_and_self_invite')
}}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
v-if="
currentUser.$homeLocation &&
currentUser.$homeLocation.worldId === worldDialog.id
"
@click="worldDialogCommand('Reset Home')">
<MagicStick class="size-4" />
{{ t('dialog.world.actions.reset_home') }}
</DropdownMenuItem>
<DropdownMenuItem v-else @click="worldDialogCommand('Make Home')">
<HomeFilled class="size-4" />
{{ t('dialog.world.actions.make_home') }}
</DropdownMenuItem>
<DropdownMenuItem @click="worldDialogCommand('Previous Instances')">
<DataLine class="size-4" />
{{ t('dialog.world.actions.show_previous_instances') }}
</DropdownMenuItem>
<template v-if="currentUser.id !== worldDialog.ref.authorId">
<DropdownMenuItem
:disabled="!worldDialog.hasPersistData"
@click="worldDialogCommand('Delete Persistent Data')">
<Upload class="size-4" />
{{ t('dialog.world.actions.delete_persistent_data') }}
</DropdownMenuItem>
</template>
<template v-else>
<DropdownMenuItem @click="worldDialogCommand('Rename')">
<Edit class="size-4" />
{{ t('dialog.world.actions.rename') }}
</DropdownMenuItem>
<DropdownMenuItem @click="worldDialogCommand('Change Description')">
<Edit class="size-4" />
{{ t('dialog.world.actions.change_description') }}
</DropdownMenuItem>
<DropdownMenuItem @click="worldDialogCommand('Change Capacity')">
<Edit class="size-4" />
{{ t('dialog.world.actions.change_capacity') }}
</DropdownMenuItem>
<DropdownMenuItem @click="worldDialogCommand('Change Recommended Capacity')">
<Edit class="size-4" />
{{ t('dialog.world.actions.change_recommended_capacity') }}
</DropdownMenuItem>
<DropdownMenuItem @click="worldDialogCommand('Change YouTube Preview')">
<Edit class="size-4" />
{{ t('dialog.world.actions.change_preview') }}
</DropdownMenuItem>
<DropdownMenuItem @click="worldDialogCommand('Change Tags')">
<Edit class="size-4" />
{{ t('dialog.world.actions.change_warnings_settings_tags') }}
</DropdownMenuItem>
<DropdownMenuItem @click="worldDialogCommand('Change Allowed Domains')">
<Edit class="size-4" />
{{ t('dialog.world.actions.change_allowed_video_player_domains') }}
</DropdownMenuItem>
<DropdownMenuItem v-if="isWindows" @click="worldDialogCommand('Change Image')">
<Picture class="size-4" />
{{ t('dialog.world.actions.change_image') }}
</DropdownMenuItem>
<DropdownMenuItem
v-if="worldDialog.ref.unityPackageUrl"
@click="worldDialogCommand('Download Unity Package')">
<Download class="size-4" />
{{ t('dialog.world.actions.download_package') }}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
v-if=" v-if="
currentUser.$homeLocation && worldDialog.ref?.tags?.includes('system_approved') ||
currentUser.$homeLocation.worldId === worldDialog.id worldDialog.ref?.tags?.includes('system_labs')
" "
:icon="MagicStick" @click="worldDialogCommand('Unpublish')">
command="Reset Home" <View class="size-4" />
divided> {{ t('dialog.world.actions.unpublish') }}
{{ t('dialog.world.actions.reset_home') }} </DropdownMenuItem>
</el-dropdown-item> <DropdownMenuItem v-else @click="worldDialogCommand('Publish')">
<el-dropdown-item v-else :icon="HomeFilled" command="Make Home" divided> <View class="size-4" />
{{ t('dialog.world.actions.make_home') }} {{ t('dialog.world.actions.publish_to_labs') }}
</el-dropdown-item> </DropdownMenuItem>
<el-dropdown-item :icon="DataLine" command="Previous Instances"> <DropdownMenuItem
{{ t('dialog.world.actions.show_previous_instances') }} :disabled="!worldDialog.hasPersistData"
</el-dropdown-item> @click="worldDialogCommand('Delete Persistent Data')">
<template v-if="currentUser.id !== worldDialog.ref.authorId"> <Upload class="size-4" />
<el-dropdown-item {{ t('dialog.world.actions.delete_persistent_data') }}
:disabled="!worldDialog.hasPersistData" </DropdownMenuItem>
:icon="Upload" <DropdownMenuItem variant="destructive" @click="worldDialogCommand('Delete')">
command="Delete Persistent Data"> <Delete class="size-4" />
{{ t('dialog.world.actions.delete_persistent_data') }} {{ t('dialog.world.actions.delete') }}
</el-dropdown-item> </DropdownMenuItem>
</template> </template>
<template v-else> </DropdownMenuContent>
<el-dropdown-item :icon="Edit" command="Rename"> </DropdownMenu>
{{ t('dialog.world.actions.rename') }}
</el-dropdown-item>
<el-dropdown-item :icon="Edit" command="Change Description">
{{ t('dialog.world.actions.change_description') }}
</el-dropdown-item>
<el-dropdown-item :icon="Edit" command="Change Capacity">
{{ t('dialog.world.actions.change_capacity') }}
</el-dropdown-item>
<el-dropdown-item :icon="Edit" command="Change Recommended Capacity">
{{ t('dialog.world.actions.change_recommended_capacity') }}
</el-dropdown-item>
<el-dropdown-item :icon="Edit" command="Change YouTube Preview">
{{ t('dialog.world.actions.change_preview') }}
</el-dropdown-item>
<el-dropdown-item :icon="Edit" command="Change Tags">
{{ t('dialog.world.actions.change_warnings_settings_tags') }}
</el-dropdown-item>
<el-dropdown-item :icon="Edit" command="Change Allowed Domains">
{{ t('dialog.world.actions.change_allowed_video_player_domains') }}
</el-dropdown-item>
<el-dropdown-item v-if="isWindows" :icon="Picture" command="Change Image">
{{ t('dialog.world.actions.change_image') }}
</el-dropdown-item>
<el-dropdown-item
v-if="worldDialog.ref.unityPackageUrl"
:icon="Download"
command="Download Unity Package">
{{ t('dialog.world.actions.download_package') }}
</el-dropdown-item>
<el-dropdown-item
v-if="
worldDialog.ref?.tags?.includes('system_approved') ||
worldDialog.ref?.tags?.includes('system_labs')
"
:icon="View"
command="Unpublish"
divided>
{{ t('dialog.world.actions.unpublish') }}
</el-dropdown-item>
<el-dropdown-item v-else :icon="View" command="Publish" divided>
{{ t('dialog.world.actions.publish_to_labs') }}
</el-dropdown-item>
<el-dropdown-item
:disabled="!worldDialog.hasPersistData"
:icon="Upload"
command="Delete Persistent Data">
{{ t('dialog.world.actions.delete_persistent_data') }}
</el-dropdown-item>
<el-dropdown-item
:icon="Delete"
command="Delete"
style="color: var(--el-color-danger)">
{{ t('dialog.world.actions.delete') }}
</el-dropdown-item>
</template>
</el-dropdown-menu>
</template>
</el-dropdown>
</div> </div>
</div> </div>
</div> </div>
@@ -431,22 +445,27 @@
{{ worldDialog.id }} {{ worldDialog.id }}
</span> </span>
<TooltipWrapper side="top" :content="t('dialog.world.info.id_tooltip')"> <TooltipWrapper side="top" :content="t('dialog.world.info.id_tooltip')">
<el-dropdown trigger="click" size="small" style="margin-left: 5px" @click.stop> <DropdownMenu>
<el-button type="default" :icon="CopyDocument" size="small" circle /> <DropdownMenuTrigger as-child>
<template #dropdown> <el-button
<el-dropdown-menu> type="default"
<el-dropdown-item @click="copyWorldId()"> :icon="CopyDocument"
{{ t('dialog.world.info.copy_id') }} size="small"
</el-dropdown-item> circle
<el-dropdown-item @click="copyWorldUrl()"> @click.stop />
{{ t('dialog.world.info.copy_url') }} </DropdownMenuTrigger>
</el-dropdown-item> <DropdownMenuContent>
<el-dropdown-item @click="copyWorldName()"> <DropdownMenuItem @click="copyWorldId()">
{{ t('dialog.world.info.copy_name') }} {{ t('dialog.world.info.copy_id') }}
</el-dropdown-item> </DropdownMenuItem>
</el-dropdown-menu> <DropdownMenuItem @click="copyWorldUrl()">
</template> {{ t('dialog.world.info.copy_url') }}
</el-dropdown> </DropdownMenuItem>
<DropdownMenuItem @click="copyWorldName()">
{{ t('dialog.world.info.copy_name') }}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TooltipWrapper> </TooltipWrapper>
</div> </div>
</div> </div>
@@ -780,6 +799,13 @@
useUserStore, useUserStore,
useWorldStore useWorldStore
} from '../../../stores'; } from '../../../stores';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '../../ui/dropdown-menu';
import { favoriteRequest, miscRequest, userRequest, worldRequest } from '../../../api'; import { favoriteRequest, miscRequest, userRequest, worldRequest } from '../../../api';
import { Badge } from '../../ui/badge'; import { Badge } from '../../ui/badge';
import { database } from '../../../service/database.js'; import { database } from '../../../service/database.js';
@@ -51,7 +51,7 @@
v-bind="{ ...$attrs, ...forwarded }" v-bind="{ ...$attrs, ...forwarded }"
:class=" :class="
cn( cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--reka-dropdown-menu-content-available-height) min-w-[8rem] origin-(--reka-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md', 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-10000 max-h-(--reka-dropdown-menu-content-available-height) min-w-[8rem] origin-(--reka-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
props.class props.class
) )
"> ">
@@ -19,7 +19,7 @@
data-slot="dropdown-menu-label" data-slot="dropdown-menu-label"
:data-inset="inset ? '' : undefined" :data-inset="inset ? '' : undefined"
v-bind="forwardedProps" v-bind="forwardedProps"
:class="cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', props.class)"> :class="cn('px-2 py-1.5 text-sm font-medium data-inset:pl-8', props.class)">
<slot /> <slot />
</DropdownMenuLabel> </DropdownMenuLabel>
</template> </template>
@@ -26,7 +26,7 @@
v-bind="forwarded" v-bind="forwarded"
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4', 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
props.class props.class
) )
"> ">
@@ -46,7 +46,7 @@
v-bind="forwarded" v-bind="forwarded"
:class=" :class="
cn( cn(
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--reka-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg', 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-10000 min-w-32 origin-(--reka-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
props.class props.class
) )
"> ">
@@ -23,7 +23,7 @@
v-bind="forwardedProps" v-bind="forwardedProps"
:class=" :class="
cn( cn(
'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8', 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-inset:pl-8',
props.class props.class
) )
"> ">