mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-04 22:06:06 +02:00
229 lines
8.0 KiB
Vue
229 lines
8.0 KiB
Vue
<template>
|
|
<div class="x-container">
|
|
<div class="header">
|
|
<div v-if="editFavoritesMode" style="display: inline-block; margin-right: 10px">
|
|
<el-button size="small" @click="clearBulkFavoriteSelection">{{ t('view.favorite.clear') }}</el-button>
|
|
<el-button size="small" @click="handleBulkCopyFavoriteSelection">{{
|
|
t('view.favorite.copy')
|
|
}}</el-button>
|
|
<el-button size="small" @click="showBulkUnfavoriteSelectionConfirm">{{
|
|
t('view.favorite.bulk_unfavorite')
|
|
}}</el-button>
|
|
</div>
|
|
<div style="display: flex; align-items: center; margin-right: 10px">
|
|
<span class="name">{{ t('view.favorite.edit_mode') }}</span>
|
|
<el-switch v-model="editFavoritesMode" style="margin-left: 5px"></el-switch>
|
|
</div>
|
|
<el-tooltip placement="bottom" :content="t('view.favorite.refresh_favorites_tooltip')" :teleported="false">
|
|
<el-button
|
|
type="default"
|
|
:loading="isFavoriteLoading"
|
|
size="small"
|
|
:icon="Refresh"
|
|
circle
|
|
@click="
|
|
refreshFavorites();
|
|
getLocalWorldFavorites();
|
|
"></el-button>
|
|
</el-tooltip>
|
|
</div>
|
|
<el-tabs v-model="currentFavoriteTab" v-loading="isFavoriteLoading" type="card" style="height: 100%">
|
|
<el-tab-pane name="friend" :label="t('view.favorite.friends.header')">
|
|
<FavoritesFriendTab
|
|
:edit-favorites-mode="editFavoritesMode"
|
|
@change-favorite-group-name="changeFavoriteGroupName" />
|
|
</el-tab-pane>
|
|
<el-tab-pane name="world" :label="t('view.favorite.worlds.header')" lazy>
|
|
<FavoritesWorldTab
|
|
:edit-favorites-mode="editFavoritesMode"
|
|
@change-favorite-group-name="changeFavoriteGroupName" />
|
|
</el-tab-pane>
|
|
<el-tab-pane name="avatar" :label="t('view.favorite.avatars.header')" lazy>
|
|
<FavoritesAvatarTab
|
|
:edit-favorites-mode="editFavoritesMode"
|
|
@change-favorite-group-name="changeFavoriteGroupName" />
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
import { Refresh } from '@element-plus/icons-vue';
|
|
import { ref } from 'vue';
|
|
import { storeToRefs } from 'pinia';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
import { favoriteRequest } from '../../api';
|
|
import { useFavoriteStore } from '../../stores';
|
|
|
|
import FavoritesAvatarTab from './components/FavoritesAvatarTab.vue';
|
|
import FavoritesFriendTab from './components/FavoritesFriendTab.vue';
|
|
import FavoritesWorldTab from './components/FavoritesWorldTab.vue';
|
|
|
|
const { t } = useI18n();
|
|
const {
|
|
favoriteFriends,
|
|
favoriteWorlds,
|
|
favoriteAvatars,
|
|
isFavoriteLoading,
|
|
avatarImportDialogInput,
|
|
worldImportDialogInput,
|
|
friendImportDialogInput,
|
|
currentFavoriteTab
|
|
} = storeToRefs(useFavoriteStore());
|
|
const {
|
|
refreshFavorites,
|
|
refreshFavoriteGroups,
|
|
clearBulkFavoriteSelection,
|
|
getLocalWorldFavorites,
|
|
handleFavoriteGroup,
|
|
showFriendImportDialog,
|
|
showWorldImportDialog,
|
|
showAvatarImportDialog
|
|
} = useFavoriteStore();
|
|
|
|
const editFavoritesMode = ref(false);
|
|
|
|
function showBulkUnfavoriteSelectionConfirm() {
|
|
const elementsTicked = [];
|
|
// check favorites type
|
|
for (const ctx of favoriteFriends.value) {
|
|
if (ctx.$selected) {
|
|
elementsTicked.push(ctx.id);
|
|
}
|
|
}
|
|
for (const ctx of favoriteWorlds.value) {
|
|
if (ctx.$selected) {
|
|
elementsTicked.push(ctx.id);
|
|
}
|
|
}
|
|
for (const ctx of favoriteAvatars.value) {
|
|
if (ctx.$selected) {
|
|
elementsTicked.push(ctx.id);
|
|
}
|
|
}
|
|
if (elementsTicked.length === 0) {
|
|
return;
|
|
}
|
|
ElMessageBox.confirm(
|
|
`Are you sure you want to unfavorite ${elementsTicked.length} favorites?
|
|
This action cannot be undone.`,
|
|
`Delete ${elementsTicked.length} favorites?`,
|
|
{
|
|
confirmButtonText: 'Confirm',
|
|
cancelButtonText: 'Cancel',
|
|
type: 'info'
|
|
}
|
|
)
|
|
.then((action) => {
|
|
if (action === 'confirm') {
|
|
bulkUnfavoriteSelection(elementsTicked);
|
|
}
|
|
})
|
|
.catch(() => {});
|
|
}
|
|
|
|
function bulkUnfavoriteSelection(elementsTicked) {
|
|
for (const id of elementsTicked) {
|
|
favoriteRequest.deleteFavorite({
|
|
objectId: id
|
|
});
|
|
}
|
|
editFavoritesMode.value = false;
|
|
}
|
|
function changeFavoriteGroupName(ctx) {
|
|
ElMessageBox.prompt(
|
|
t('prompt.change_favorite_group_name.description'),
|
|
t('prompt.change_favorite_group_name.header'),
|
|
{
|
|
distinguishCancelAndClose: true,
|
|
cancelButtonText: t('prompt.change_favorite_group_name.cancel'),
|
|
confirmButtonText: t('prompt.change_favorite_group_name.change'),
|
|
inputPlaceholder: t('prompt.change_favorite_group_name.input_placeholder'),
|
|
inputValue: ctx.displayName,
|
|
inputPattern: /\S+/,
|
|
inputErrorMessage: t('prompt.change_favorite_group_name.input_error')
|
|
}
|
|
)
|
|
.then(({ value }) => {
|
|
favoriteRequest
|
|
.saveFavoriteGroup({
|
|
type: ctx.type,
|
|
group: ctx.name,
|
|
displayName: value
|
|
})
|
|
.then((args) => {
|
|
handleFavoriteGroup({
|
|
json: args.json,
|
|
params: {
|
|
favoriteGroupId: args.json.id
|
|
}
|
|
});
|
|
ElMessage({
|
|
message: t('prompt.change_favorite_group_name.message.success'),
|
|
type: 'success'
|
|
});
|
|
// load new group name
|
|
refreshFavoriteGroups();
|
|
});
|
|
})
|
|
.catch(() => {});
|
|
}
|
|
|
|
function handleBulkCopyFavoriteSelection() {
|
|
let idList = '';
|
|
switch (currentFavoriteTab.value) {
|
|
case 'friend':
|
|
for (const ctx of favoriteFriends.value) {
|
|
if (ctx.$selected) {
|
|
idList += `${ctx.id}\n`;
|
|
}
|
|
}
|
|
friendImportDialogInput.value = idList;
|
|
showFriendImportDialog();
|
|
|
|
break;
|
|
|
|
case 'world':
|
|
for (const ctx of favoriteWorlds.value) {
|
|
if (ctx.$selected) {
|
|
idList += `${ctx.id}\n`;
|
|
}
|
|
}
|
|
worldImportDialogInput.value = idList;
|
|
showWorldImportDialog();
|
|
|
|
break;
|
|
|
|
case 'avatar':
|
|
for (const ctx of favoriteAvatars.value) {
|
|
if (ctx.$selected) {
|
|
idList += `${ctx.id}\n`;
|
|
}
|
|
}
|
|
avatarImportDialogInput.value = idList;
|
|
showAvatarImportDialog();
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
console.log('Favorite selection\n', idList);
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.header {
|
|
font-size: 13px;
|
|
position: absolute;
|
|
display: flex;
|
|
align-items: center;
|
|
right: 0;
|
|
z-index: 1;
|
|
margin-right: 15px;
|
|
}
|
|
</style>
|