diff --git a/html/src/app.js b/html/src/app.js index dbcf20c9..f596c0ca 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -17159,6 +17159,18 @@ speechSynthesis.getVoices(); return style; }; + $app.methods.userFavoriteWorldsStatusForFavTab = function (visibility) { + let style = ''; + if (visibility === 'public') { + style = ''; + } else if (visibility === 'friends') { + style = 'success'; + } else { + style = 'info'; + } + return style; + }; + $app.methods.changeWorldGroupVisibility = function (name, visibility) { var params = { type: 'world', @@ -19630,6 +19642,23 @@ speechSynthesis.getVoices(); this.worldExportDialogVisible = true; }; + $app.methods.handleCopyWorldExportData = function (event) { + event.target.tagName === 'TEXTAREA' && event.target.select(); + navigator.clipboard + .writeText(this.worldExportContent) + .then(() => { + this.$message({ + message: 'Copied successfully!', + type: 'success', + duration: 2000 + }); + }) + .catch((err) => { + console.error('Copy failed:', err); + this.$message.error('Copy failed!'); + }); + }; + $app.methods.updateWorldExportDialog = function () { const formatter = function (str) { if (/[\x00-\x1f,"]/.test(str) === true) { @@ -19895,6 +19924,23 @@ speechSynthesis.getVoices(); this.avatarExportDialogVisible = true; }; + $app.methods.handleCopyAvatarExportData = function (event) { + event.target.tagName === 'TEXTAREA' && event.target.select(); + navigator.clipboard + .writeText(this.avatarExportContent) + .then(() => { + this.$message({ + message: 'Copied successfully!', + type: 'success', + duration: 2000 + }); + }) + .catch((err) => { + console.error('Copy failed:', err); + this.$message.error('Copy failed!'); + }); + }; + /** * Update the content of the avatar export dialog based on the selected options */ @@ -20136,6 +20182,23 @@ speechSynthesis.getVoices(); this.friendExportDialogVisible = true; }; + $app.methods.handleCopyFriendExportData = function (event) { + event.target.tagName === 'TEXTAREA' && event.target.select(); + navigator.clipboard + .writeText(this.friendExportContent) + .then(() => { + this.$message({ + message: 'Copied successfully!', + type: 'success', + duration: 2000 + }); + }) + .catch((err) => { + console.error('Copy failed:', err); + this.$message.error('Copy failed!'); + }); + }; + $app.methods.updateFriendExportDialog = function () { var _ = function (str) { if (/[\x00-\x1f,"]/.test(str) === true) { diff --git a/html/src/app.scss b/html/src/app.scss index 5926b9bc..3eacd135 100644 --- a/html/src/app.scss +++ b/html/src/app.scss @@ -407,7 +407,6 @@ img.friends-list-avatar { object-fit: cover; } -.x-friend-item > .avatar.offline > img, .x-friend-item > .avatar.active > img { filter: grayscale(1); } @@ -920,6 +919,11 @@ i.x-status-icon.red { line-height: 17px; } +// feed table detail time tag line-height +.el-table__expanded-cell .el-tag--mini { + line-height: 17px; +} + // User dialog memo: input count background color .x-friend-item:hover .el-input__count { background: #f0f0f0; @@ -929,3 +933,7 @@ i.x-status-icon.red { .x-app > .x-container { padding-top: 15px; } + +.el-collapse-item .el-tag--mini { + line-height: 17px; +} diff --git a/html/src/mixins/dialogs/favoritesDialog.pug b/html/src/mixins/dialogs/favoritesDialog.pug index 1eeef7b7..c2abab6d 100644 --- a/html/src/mixins/dialogs/favoritesDialog.pug +++ b/html/src/mixins/dialogs/favoritesDialog.pug @@ -52,39 +52,42 @@ mixin favoritesDialog() template(v-for="group in localWorldFavoriteGroups" :key="group") el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldExportLocalGroup(group)") {{ group }} ({{ localWorldFavorites[group].length }}) br - el-input(type="textarea" v-if="worldExportDialogVisible" v-model="worldExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()") + el-input(type="textarea" v-if="worldExportDialogVisible" v-model="worldExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="handleCopyWorldExportData") //- dialog: World import dialog el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="worldImportDialog" :visible.sync="worldImportDialog.visible" :title="$t('dialog.world_import.header')" width="650px") - div(style="font-size:12px") - | {{ $t('dialog.world_import.description') }} - el-input(type="textarea" v-model="worldImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:15px") - el-button(size="small" @click="processWorldImportList" :disabled="!worldImportDialog.input") {{ $t('dialog.world_import.process_list') }} - span(v-if="worldImportDialog.progress" style="margin-top:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.world_import.process_progress') }} {{ worldImportDialog.progress }}/{{ worldImportDialog.progressTotal }} - br - el-dropdown(@click.native.stop trigger="click" size="small" style="margin-right:5px") - el-button(size="mini") - span(v-if="worldImportDialog.worldImportFavoriteGroup") {{ worldImportDialog.worldImportFavoriteGroup.displayName }} ({{ worldImportDialog.worldImportFavoriteGroup.count }}/{{ worldImportDialog.worldImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right] - span(v-else) {{ $t('dialog.world_import.select_vrchat_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] - el-dropdown-menu(#default="dropdown") - template(v-for="groupAPI in API.favoriteWorldGroups" :key="groupAPI.name") - el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }}) - el-dropdown(@click.native.stop trigger="click" size="small" style="margin:5px") - el-button(size="mini") - span(v-if="worldImportDialog.worldImportLocalFavoriteGroup") {{ worldImportDialog.worldImportLocalFavoriteGroup }} ({{ getLocalWorldFavoriteGroupLength(worldImportDialog.worldImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right] - span(v-else) {{ $t('dialog.world_import.select_local_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] - el-dropdown-menu(#default="dropdown") - template(v-for="group in localWorldFavoriteGroups" :key="group") - el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldImportLocalGroup(group)" ) {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }}) - el-button(size="small" @click="importWorldImportTable" style="margin:5px" :disabled="worldImportTable.data.length === 0 || (!worldImportDialog.worldImportFavoriteGroup && !worldImportDialog.worldImportLocalFavoriteGroup)") {{ $t('dialog.world_import.import') }} - el-button(v-if="worldImportDialog.loading" size="small" @click="cancelWorldImport" style="margin-top:10px") {{ $t('dialog.world_import.cancel') }} - span(v-if="worldImportDialog.worldImportFavoriteGroup") {{ worldImportTable.data.length }} / {{ worldImportDialog.worldImportFavoriteGroup.capacity - worldImportDialog.worldImportFavoriteGroup.count }} + div(style="display:flex;align-items:center;justify-content:space-between") + div(style="font-size:12px") {{ $t('dialog.world_import.description') }} + div(style="display:flex;align-items:center;") + div(v-if="worldImportDialog.progress") {{ $t('dialog.world_import.process_progress') }} {{ worldImportDialog.progress }} / {{ worldImportDialog.progressTotal }} #[i.el-icon-loading(style="margin:0 5px")] + el-button(v-if="worldImportDialog.loading" size="small" @click="cancelWorldImport") {{ $t('dialog.world_import.cancel') }} + el-button(v-else size="small" @click="processWorldImportList" :disabled="!worldImportDialog.input") {{ $t('dialog.world_import.process_list') }} + el-input(type="textarea" v-model="worldImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:10px") + div(style="display:flex;align-items:center;justify-content:space-between;margin-top:5px") + div + el-dropdown(@click.native.stop trigger="click" size="small" style="margin-right:5px") + el-button(size="mini") + span(v-if="worldImportDialog.worldImportFavoriteGroup") {{ worldImportDialog.worldImportFavoriteGroup.displayName }} ({{ worldImportDialog.worldImportFavoriteGroup.count }}/{{ worldImportDialog.worldImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right] + span(v-else) {{ $t('dialog.world_import.select_vrchat_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] + el-dropdown-menu(#default="dropdown") + template(v-for="groupAPI in API.favoriteWorldGroups" :key="groupAPI.name") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }}) + el-dropdown(@click.native.stop trigger="click" size="small" style="margin:5px") + el-button(size="mini") + span(v-if="worldImportDialog.worldImportLocalFavoriteGroup") {{ worldImportDialog.worldImportLocalFavoriteGroup }} ({{ getLocalWorldFavoriteGroupLength(worldImportDialog.worldImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right] + span(v-else) {{ $t('dialog.world_import.select_local_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] + el-dropdown-menu(#default="dropdown") + template(v-for="group in localWorldFavoriteGroups" :key="group") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldImportLocalGroup(group)" ) {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }}) + span(v-if="worldImportDialog.worldImportFavoriteGroup" style="margin-left:5px") {{ worldImportTable.data.length }} / {{ worldImportDialog.worldImportFavoriteGroup.capacity - worldImportDialog.worldImportFavoriteGroup.count }} + div + el-button(size="small" @click="clearWorldImportTable" :disabled="worldImportTable.data.length === 0") {{ $t('dialog.world_import.clear_table') }} + el-button(size="small" type="primary" @click="importWorldImportTable" style="margin:5px" :disabled="worldImportTable.data.length === 0 || (!worldImportDialog.worldImportFavoriteGroup && !worldImportDialog.worldImportLocalFavoriteGroup)") {{ $t('dialog.world_import.import') }} span(v-if="worldImportDialog.importProgress" style="margin:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.world_import.import_progress') }} {{ worldImportDialog.importProgress }}/{{ worldImportDialog.importProgressTotal }} br - el-button(size="small" @click="clearWorldImportTable") {{ $t('dialog.world_import.clear_table') }} template(v-if="worldImportDialog.errors") - el-button(size="small" @click="worldImportDialog.errors = ''" style="margin-left:5px") {{ $t('dialog.world_import.clear_errors') }} - h2(style="font-weight:bold;margin:0") {{ $t('dialog.world_import.errors') }} + el-button(size="small" @click="worldImportDialog.errors = ''") {{ $t('dialog.world_import.clear_errors') }} + h2(style="font-weight:bold;margin:5px 0") {{ $t('dialog.world_import.errors') }} pre(v-text="worldImportDialog.errors" style="white-space:pre-wrap;font-size:12px") data-tables(v-if="worldImportDialog.visible" v-bind="worldImportTable" v-loading="worldImportDialog.loading" style="margin-top:10px") el-table-column(:label="$t('table.import.image')" width="70" prop="thumbnailImageUrl") @@ -100,9 +103,7 @@ mixin favoritesDialog() span.x-link(v-text="scope.row.authorName" @click="showUserDialog(scope.row.authorId)") el-table-column(:label="$t('table.import.status')" width="70" prop="releaseStatus") template(v-once #default="scope") - span(v-text="scope.row.releaseStatus" v-if="scope.row.releaseStatus === 'public'" style="color:#67c23a") - span(v-text="scope.row.releaseStatus" v-else-if="scope.row.releaseStatus === 'private'" style="color:#f56c6c") - span(v-text="scope.row.releaseStatus" v-else) + span(v-text="scope.row.releaseStatus.charAt(0).toUpperCase() + scope.row.releaseStatus.slice(1)" :style="{ color: scope.row.releaseStatus === 'public' ? '#67c23a' : scope.row.releaseStatus === 'private' ? '#f56c6c' : undefined }") el-table-column(:label="$t('table.import.action')" width="90" align="right") template(v-once #default="scope") el-button(type="text" icon="el-icon-close" size="mini" @click="deleteItemWorldImport(scope.row)") @@ -129,39 +130,42 @@ mixin favoritesDialog() template(v-for="group in localAvatarFavoriteGroups" :key="group") el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarExportLocalGroup(group)" ) {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }}) br - el-input(type="textarea" v-if="avatarExportDialogVisible" v-model="avatarExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()") + el-input(type="textarea" v-if="avatarExportDialogVisible" v-model="avatarExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="handleCopyAvatarExportData") //- dialog: Avatar import dialog el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="avatarImportDialog" :visible.sync="avatarImportDialog.visible" :title="$t('dialog.avatar_import.header')" width="650px") - div(style="font-size:12px") - | {{ $t('dialog.avatar_import.description') }} - el-input(type="textarea" v-model="avatarImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:15px") - el-button(size="small" @click="processAvatarImportList" :disabled="!avatarImportDialog.input") {{ $t('dialog.avatar_import.process_list') }} - span(v-if="avatarImportDialog.progress" style="margin-top:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.avatar_import.process_progress') }} {{ avatarImportDialog.progress }}/{{ avatarImportDialog.progressTotal }} - br - el-dropdown(@click.native.stop trigger="click" size="small") - el-button(size="mini") - span(v-if="avatarImportDialog.avatarImportFavoriteGroup") {{ avatarImportDialog.avatarImportFavoriteGroup.displayName }} ({{ avatarImportDialog.avatarImportFavoriteGroup.count }}/{{ avatarImportDialog.avatarImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right] - span(v-else) {{ $t('dialog.avatar_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] - el-dropdown-menu(#default="dropdown") - template(v-for="groupAPI in API.favoriteAvatarGroups" :key="groupAPI.name") - el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }}) - el-dropdown(@click.native.stop trigger="click" size="small" style="margin:5px") - el-button(size="mini") - span(v-if="avatarImportDialog.avatarImportLocalFavoriteGroup") {{ avatarImportDialog.avatarImportLocalFavoriteGroup }} ({{ getLocalAvatarFavoriteGroupLength(avatarImportDialog.avatarImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right] - span(v-else) {{ $t('dialog.avatar_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] - el-dropdown-menu(#default="dropdown") - template(v-for="group in localAvatarFavoriteGroups" :key="group") - el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarImportLocalGroup(group)" ) {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }}) - el-button(size="small" @click="importAvatarImportTable" style="margin:5px" :disabled="avatarImportTable.data.length === 0 || (!avatarImportDialog.avatarImportFavoriteGroup && !avatarImportDialog.avatarImportLocalFavoriteGroup)") {{ $t('dialog.avatar_import.import') }} - el-button(v-if="avatarImportDialog.loading" size="small" @click="cancelAvatarImport" style="margin-top:10px") {{ $t('dialog.avatar_import.cancel') }} - span(v-if="avatarImportDialog.avatarImportFavoriteGroup") {{ avatarImportTable.data.length }} / {{ avatarImportDialog.avatarImportFavoriteGroup.capacity - avatarImportDialog.avatarImportFavoriteGroup.count }} + div(style="display:flex;align-items:center;justify-content:space-between") + div(style="font-size:12px") {{ $t('dialog.avatar_import.description') }} + div(style="display:flex;align-items:center;") + div(v-if="avatarImportDialog.progress") {{ $t('dialog.avatar_import.process_progress') }} {{ avatarImportDialog.progress }} / {{ avatarImportDialog.progressTotal }} #[i.el-icon-loading(style="margin:0 5px")] + el-button(v-if="avatarImportDialog.loading" size="small" @click="cancelAvatarImport") {{ $t('dialog.avatar_import.cancel') }} + el-button(v-else size="small" @click="processAvatarImportList" :disabled="!avatarImportDialog.input") {{ $t('dialog.avatar_import.process_list') }} + el-input(type="textarea" v-model="avatarImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:10px") + div(style="display:flex;align-items:center;justify-content:space-between;margin-top:5px") + div + el-dropdown(@click.native.stop trigger="click" size="small") + el-button(size="mini") + span(v-if="avatarImportDialog.avatarImportFavoriteGroup") {{ avatarImportDialog.avatarImportFavoriteGroup.displayName }} ({{ avatarImportDialog.avatarImportFavoriteGroup.count }}/{{ avatarImportDialog.avatarImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right] + span(v-else) {{ $t('dialog.avatar_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] + el-dropdown-menu(#default="dropdown") + template(v-for="groupAPI in API.favoriteAvatarGroups" :key="groupAPI.name") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }}) + el-dropdown(@click.native.stop trigger="click" size="small" style="margin:5px") + el-button(size="mini") + span(v-if="avatarImportDialog.avatarImportLocalFavoriteGroup") {{ avatarImportDialog.avatarImportLocalFavoriteGroup }} ({{ getLocalAvatarFavoriteGroupLength(avatarImportDialog.avatarImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right] + span(v-else) {{ $t('dialog.avatar_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] + el-dropdown-menu(#default="dropdown") + template(v-for="group in localAvatarFavoriteGroups" :key="group") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarImportLocalGroup(group)" ) {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }}) + span(v-if="avatarImportDialog.avatarImportFavoriteGroup" style="margin-left:5px") {{ avatarImportTable.data.length }} / {{ avatarImportDialog.avatarImportFavoriteGroup.capacity - avatarImportDialog.avatarImportFavoriteGroup.count }} + div + el-button(size="small" @click="clearAvatarImportTable") {{ $t('dialog.avatar_import.clear_table') }} + el-button(size="small" type="primary" @click="importAvatarImportTable" style="margin:5px" :disabled="avatarImportTable.data.length === 0 || (!avatarImportDialog.avatarImportFavoriteGroup && !avatarImportDialog.avatarImportLocalFavoriteGroup)") {{ $t('dialog.avatar_import.import') }} span(v-if="avatarImportDialog.importProgress" style="margin:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.avatar_import.import_progress') }} {{ avatarImportDialog.importProgress }}/{{ avatarImportDialog.importProgressTotal }} br - el-button(size="small" @click="clearAvatarImportTable") {{ $t('dialog.avatar_import.clear_table') }} template(v-if="avatarImportDialog.errors") - el-button(size="small" @click="avatarImportDialog.errors = ''" style="margin-left:5px") {{ $t('dialog.avatar_import.clear_errors') }} - h2(style="font-weight:bold;margin:0") {{ $t('dialog.avatar_import.errors') }} + el-button(size="small" @click="avatarImportDialog.errors = ''") {{ $t('dialog.avatar_import.clear_errors') }} + h2(style="font-weight:bold;margin:5px 0") {{ $t('dialog.avatar_import.errors') }} pre(v-text="avatarImportDialog.errors" style="white-space:pre-wrap;font-size:12px") data-tables(v-if="avatarImportDialog.visible" v-bind="avatarImportTable" v-loading="avatarImportDialog.loading" style="margin-top:10px") el-table-column(:label="$t('table.import.image')" width="70" prop="thumbnailImageUrl") @@ -177,9 +181,7 @@ mixin favoritesDialog() span.x-link(v-text="scope.row.authorName" @click="showUserDialog(scope.row.authorId)") el-table-column(:label="$t('table.import.status')" width="70" prop="releaseStatus") template(v-once #default="scope") - span(v-text="scope.row.releaseStatus" v-if="scope.row.releaseStatus === 'public'" style="color:#67c23a") - span(v-text="scope.row.releaseStatus" v-else-if="scope.row.releaseStatus === 'private'" style="color:#f56c6c") - span(v-text="scope.row.releaseStatus" v-else) + span(v-text="scope.row.releaseStatus.charAt(0).toUpperCase() + scope.row.releaseStatus.slice(1)" :style="{ color: scope.row.releaseStatus === 'public' ? '#67c23a' : scope.row.releaseStatus === 'private' ? '#f56c6c' : undefined }") el-table-column(:label="$t('table.import.action')" width="90" align="right") template(v-once #default="scope") el-button(type="text" icon="el-icon-close" size="mini" @click="deleteItemAvatarImport(scope.row)") @@ -195,32 +197,35 @@ mixin favoritesDialog() template(v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name") el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectFriendExportGroup(groupAPI)") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }}) br - el-input(type="textarea" v-if="friendExportDialogVisible" v-model="friendExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()") - + el-input(type="textarea" v-if="friendExportDialogVisible" v-model="friendExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="handleCopyFriendExportData") + //- dialog: Friend import dialog el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="friendImportDialog" :visible.sync="friendImportDialog.visible" :title="$t('dialog.friend_import.header')" width="650px") - div(style="font-size:12px") - | {{ $t('dialog.friend_import.description') }} - el-input(type="textarea" v-model="friendImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:15px") - el-button(size="small" @click="processFriendImportList" :disabled="!friendImportDialog.input") {{ $t('dialog.friend_import.process_list') }} - span(v-if="friendImportDialog.progress" style="margin-top:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.friend_import.process_progress') }} {{ friendImportDialog.progress }}/{{ friendImportDialog.progressTotal }} - br - el-dropdown(@click.native.stop trigger="click" size="small") - el-button(size="mini") - span(v-if="friendImportDialog.friendImportFavoriteGroup") {{ friendImportDialog.friendImportFavoriteGroup.displayName }} ({{ friendImportDialog.friendImportFavoriteGroup.count }}/{{ friendImportDialog.friendImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right] - span(v-else) {{ $t('dialog.friend_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] - el-dropdown-menu(#default="dropdown") - template(v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name") - el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectFriendImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }}) - el-button(size="small" @click="importFriendImportTable" style="margin:5px" :disabled="friendImportTable.data.length === 0 || !friendImportDialog.friendImportFavoriteGroup") {{ $t('dialog.friend_import.import') }} - el-button(v-if="friendImportDialog.loading" size="small" @click="cancelFriendImport" style="margin-top:10px") {{ $t('dialog.friend_import.cancel') }} - span(v-if="friendImportDialog.friendImportFavoriteGroup") {{ friendImportTable.data.length }} / {{ friendImportDialog.friendImportFavoriteGroup.capacity - friendImportDialog.friendImportFavoriteGroup.count }} + div(style="display:flex;align-items:center;justify-content:space-between") + div(style="font-size:12px") {{ $t('dialog.friend_import.description') }} + div(style="display:flex;align-items:center;") + div(v-if="friendImportDialog.progress") {{ $t('dialog.friend_import.process_progress') }} {{ friendImportDialog.progress }} / {{ friendImportDialog.progressTotal }} #[i.el-icon-loading(style="margin:0 5px")] + el-button(v-if="friendImportDialog.loading" size="small" @click="cancelFriendImport") {{ $t('dialog.friend_import.cancel') }} + el-button(v-else size="small" @click="processFriendImportList" :disabled="!friendImportDialog.input") {{ $t('dialog.friend_import.process_list') }} + el-input(type="textarea" v-model="friendImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:10px") + div(style="display:flex;align-items:center;justify-content:space-between;margin-top:5px") + div + el-dropdown(@click.native.stop trigger="click" size="small") + el-button(size="mini") + span(v-if="friendImportDialog.friendImportFavoriteGroup") {{ friendImportDialog.friendImportFavoriteGroup.displayName }} ({{ friendImportDialog.friendImportFavoriteGroup.count }}/{{ friendImportDialog.friendImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right] + span(v-else) {{ $t('dialog.friend_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right] + el-dropdown-menu(#default="dropdown") + template(v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectFriendImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }}) + span(v-if="friendImportDialog.friendImportFavoriteGroup" style="margin-left:5px") {{ friendImportTable.data.length }} / {{ friendImportDialog.friendImportFavoriteGroup.capacity - friendImportDialog.friendImportFavoriteGroup.count }} + div + el-button(size="small" @click="clearFriendImportTable" :disabled="friendImportTable.data.length === 0") {{ $t('dialog.friend_import.clear_table') }} + el-button(size="small" type="primary" @click="importFriendImportTable" style="margin:5px" :disabled="friendImportTable.data.length === 0 || !friendImportDialog.friendImportFavoriteGroup") {{ $t('dialog.friend_import.import') }} span(v-if="friendImportDialog.importProgress" style="margin:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.friend_import.import_progress') }} {{ friendImportDialog.importProgress }}/{{ friendImportDialog.importProgressTotal }} br - el-button(size="small" @click="clearFriendImportTable") {{ $t('dialog.friend_import.clear_table') }} template(v-if="friendImportDialog.errors") - el-button(size="small" @click="friendImportDialog.errors = ''" style="margin-left:5px") {{ $t('dialog.friend_import.clear_errors') }} - h2(style="font-weight:bold;margin:0") {{ $t('dialog.friend_import.errors') }} + el-button(size="small" @click="friendImportDialog.errors = ''") {{ $t('dialog.friend_import.clear_errors') }} + h2(style="font-weight:bold;margin:5px 0") {{ $t('dialog.friend_import.errors') }} pre(v-text="friendImportDialog.errors" style="white-space:pre-wrap;font-size:12px") data-tables(v-if="friendImportDialog.visible" v-bind="friendImportTable" v-loading="friendImportDialog.loading" style="margin-top:10px") el-table-column(:label="$t('table.import.image')" width="70" prop="currentAvatarThumbnailImageUrl") diff --git a/html/src/mixins/tabs/favorites.pug b/html/src/mixins/tabs/favorites.pug index 69a526d3..c2911e93 100644 --- a/html/src/mixins/tabs/favorites.pug +++ b/html/src/mixins/tabs/favorites.pug @@ -13,11 +13,15 @@ mixin favoritesTab() el-tabs(ref="favoriteTabRef" type="card" v-loading="API.isFavoriteLoading" style="height:100%") el-tab-pane(:label="$t('view.favorite.friends.header')") el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '0'" style="border:0") - el-button(size="small" @click="showFriendExportDialog") {{ $t('view.favorite.export') }} - el-button(size="small" @click="showFriendImportDialog" style="margin-left:5px") {{ $t('view.favorite.import') }} - div(style="display:flex;align-items:center;float:right;font-size:13px;margin-right:10px") - span.name(style="margin-right:5px") {{ $t('view.favorite.sort_by') }} - el-switch(v-model="sortFavorites" :inactive-text="$t('view.settings.appearance.appearance.sort_favorite_by_name')" :active-text="$t('view.settings.appearance.appearance.sort_favorite_by_date')" @change="saveSortFavoritesOption") + div(style="display:flex;align-items:center;justify-content:space-between") + div + el-button(size="small" @click="showFriendExportDialog") {{ $t('view.favorite.export') }} + el-button(size="small" @click="showFriendImportDialog" style="margin-left:5px") {{ $t('view.favorite.import') }} + div(style="display:flex;align-items:center;font-size:13px;margin-right:10px") + span.name(style="margin-right:5px;line-height:10px;") {{ $t('view.favorite.sort_by') }} + el-radio-group(v-model="sortFavorites" @change="saveSortFavoritesOption") + el-radio(:label="false") {{ $t('view.settings.appearance.appearance.sort_favorite_by_name') }} + el-radio(:label="true") {{ $t('view.settings.appearance.appearance.sort_favorite_by_date') }} el-collapse-item(v-for="group in API.favoriteFriendGroups" :key="group.name") template(slot="title") span(v-text="group.displayName ? group.displayName : group.name" style="font-weight:bold;font-size:14px;margin-left:10px") @@ -54,15 +58,20 @@ mixin favoritesTab() .detail span(v-text="favorite.name || favorite.id") el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px") + div(v-else style="height:20px;width:100%;display:flex;align-items:center;justify-content:center;color:rgb(144, 147, 153)") + span No Data el-tab-pane(:label="$t('view.favorite.worlds.header')") el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '1'" style="border:0") - el-button(size="small" @click="showWorldExportDialog") {{ $t('view.favorite.export') }} - el-button(size="small" @click="showWorldImportDialog" style="margin-left:5px") {{ $t('view.favorite.import') }} - div(style="display:flex;align-items:center;float:right;font-size:13px;margin-right:10px") - span.name(style="margin-right:5px") {{ $t('view.favorite.sort_by') }} - el-switch(v-model="sortFavorites" :inactive-text="$t('view.settings.appearance.appearance.sort_favorite_by_name')" :active-text="$t('view.settings.appearance.appearance.sort_favorite_by_date')" @change="saveSortFavoritesOption") - span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.search') }} - el-input(v-model="worldFavoriteSearch" @input="searchWorldFavorites" clearable size="mini" :placeholder="$t('view.favorite.worlds.search')" style="width:300px;margin-top:10px") + div(style="display:flex;align-items:center;justify-content:space-between") + div + el-button(size="small" @click="showWorldExportDialog") {{ $t('view.favorite.export') }} + el-button(size="small" @click="showWorldImportDialog" style="margin-left:5px") {{ $t('view.favorite.import') }} + div(style="display:flex;align-items:center;font-size:13px;margin-right:10px") + span.name(style="margin-right:5px;line-height:10px;") {{ $t('view.favorite.sort_by') }} + el-radio-group(v-model="sortFavorites" @change="saveSortFavoritesOption" style="margin-right:12px") + el-radio(:label="false") {{ $t('view.settings.appearance.appearance.sort_favorite_by_name') }} + el-radio(:label="true") {{ $t('view.settings.appearance.appearance.sort_favorite_by_date') }} + el-input(v-model="worldFavoriteSearch" @input="searchWorldFavorites" clearable size="mini" :placeholder="$t('view.favorite.worlds.search')" style="width:200px;") .x-friend-list(style="margin-top:10px") div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in worldFavoriteSearchResults" :key="favorite.id" @click="showWorldDialog(favorite.id)") .x-friend-item @@ -81,18 +90,19 @@ mixin favoritesTab() span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.vrchat_favorites') }} el-collapse-item(v-for="group in API.favoriteWorldGroups" :key="group.name") template(slot="title") - span(v-text="group.displayName ? group.displayName : group.name" style="font-weight:bold;font-size:14px;margin-left:10px") - i.x-status-icon(style="margin-left:5px" :class="userFavoriteWorldsStatus(group.visibility)") - span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }} - el-tooltip(placement="top" :content="$t('view.favorite.visibility_tooltip')" :disabled="hideTooltips") - el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:10px") - el-button(type="default" icon="el-icon-view" size="mini" circle) - el-dropdown-menu(#default="dropdown") - el-dropdown-item(v-if="group.visibility !== visibility" v-for="visibility in worldGroupVisibilityOptions" :key="visibility" style="display:block;margin:10px 0" v-text="visibility" @click.native="changeWorldGroupVisibility(group.name, visibility)") - el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips") - el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:5px") - el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips") - el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px") + div(style="display:flex;align-items:center;") + span(v-text="group.displayName ? group.displayName : group.name" style="font-weight:bold;font-size:14px;margin-left:10px") + el-tag(style="margin-left:5px" size="mini" :type="userFavoriteWorldsStatusForFavTab(group.visibility)" effect="plain") {{ group.visibility.charAt(0).toUpperCase() + group.visibility.slice(1) }} + span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }} + el-tooltip(placement="top" :content="$t('view.favorite.visibility_tooltip')" :disabled="hideTooltips") + el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:10px") + el-button(type="default" icon="el-icon-view" size="mini" circle) + el-dropdown-menu(#default="dropdown") + el-dropdown-item(v-if="group.visibility !== visibility" v-for="visibility in worldGroupVisibilityOptions" :key="visibility" style="display:block;margin:10px 0" v-text="visibility.charAt(0).toUpperCase() + visibility.slice(1)" @click.native="changeWorldGroupVisibility(group.name, visibility)") + el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips") + el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:5px") + el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips") + el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px") .x-friend-list(v-if="group.count" style="margin-top:10px") div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteWorlds" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showWorldDialog(favorite.id)") .x-friend-item @@ -129,6 +139,8 @@ mixin favoritesTab() el-tooltip(v-if="favorite.deleted" placement="left" :content="$t('view.favorite.unavailable_tooltip')") i.el-icon-warning(style="color:#f56c6c;margin-left:5px") el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px") + div(v-else style="height:20px;width:100%;display:flex;align-items:center;justify-content:center;color:rgb(144, 147, 153)") + span No Data span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.local_favorites') }} br el-button(size="small" @click="promptNewLocalWorldFavoriteGroup") {{ $t('view.favorite.worlds.new_group') }} @@ -144,7 +156,7 @@ mixin favoritesTab() el-button(@click.stop="promptLocalWorldFavoriteGroupRename(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px") el-tooltip(placement="right" :content="$t('view.favorite.delete_tooltip')" :disabled="hideTooltips") el-button(@click.stop="promptLocalWorldFavoriteGroupDelete(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px") - .x-friend-list(style="margin-top:10px") + .x-friend-list(style="margin-top:10px" v-if="localWorldFavorites[group].length") div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in localWorldFavorites[group]" :key="favorite.id" @click="showWorldDialog(favorite.id)") .x-friend-item template(v-if="favorite.name") @@ -172,15 +184,20 @@ mixin favoritesTab() .detail span(v-text="favorite.id") el-button(type="text" icon="el-icon-close" size="mini" @click.stop="removeLocalWorldFavorite(favorite.id, group)" style="margin-left:5px") + div(v-else style="height:20px;width:100%;display:flex;align-items:center;justify-content:center;color:rgb(144, 147, 153)") + span No Data el-tab-pane(:label="$t('view.favorite.avatars.header')") el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '2'" style="border:0") - el-button(size="small" @click="showAvatarExportDialog") {{ $t('view.favorite.export') }} - el-button(size="small" @click="showAvatarImportDialog" style="margin-left:5px") {{ $t('view.favorite.import') }} - div(style="display:flex;align-items:center;float:right;font-size:13px;margin-right:10px") - span.name(style="margin-right:5px") {{ $t('view.favorite.sort_by') }} - el-switch(v-model="sortFavorites" :inactive-text="$t('view.settings.appearance.appearance.sort_favorite_by_name')" :active-text="$t('view.settings.appearance.appearance.sort_favorite_by_date')" @change="saveSortFavoritesOption") - span(style="display:block;margin-top:20px") {{ $t('view.favorite.avatars.search') }} - el-input(v-model="avatarFavoriteSearch" @input="searchAvatarFavorites" clearable size="mini" :placeholder="$t('view.favorite.avatars.search')" style="width:300px;margin-top:10px") + div(style="display:flex;align-items:center;justify-content:space-between") + div + el-button(size="small" @click="showAvatarExportDialog") {{ $t('view.favorite.export') }} + el-button(size="small" @click="showAvatarImportDialog" style="margin-left:5px") {{ $t('view.favorite.import') }} + div(style="display:flex;align-items:center;font-size:13px;margin-right:10px") + span.name(style="margin-right:5px;line-height:10px;") {{ $t('view.favorite.sort_by') }} + el-radio-group(v-model="sortFavorites" @change="saveSortFavoritesOption" style="margin-right:12px") + el-radio(:label="false") {{ $t('view.settings.appearance.appearance.sort_favorite_by_name') }} + el-radio(:label="true") {{ $t('view.settings.appearance.appearance.sort_favorite_by_date') }} + el-input(v-model="avatarFavoriteSearch" @input="searchAvatarFavorites" clearable size="mini" :placeholder="$t('view.favorite.avatars.search')" style="width:200px;") .x-friend-list(style="margin-top:10px") div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in avatarFavoriteSearchResults" :key="favorite.id" @click="showAvatarDialog(favorite.id)") .x-friend-item @@ -237,6 +254,8 @@ mixin favoritesTab() .detail span.name(v-text="favorite.name || favorite.id") el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px") + div(v-else style="height:20px;width:100%;display:flex;align-items:center;justify-content:center;color:rgb(144, 147, 153)") + span No Data el-collapse-item template(slot="title") span(style="font-weight:bold;font-size:14px;margin-left:10px") Local History @@ -259,6 +278,8 @@ mixin favoritesTab() template(v-else) el-tooltip(placement="right" content="Favorite" :disabled="hideTooltips") el-button(@click.stop="showFavoriteDialog('avatar', favorite.id)" type="default" icon="el-icon-star-off" size="mini" circle style="margin-left:5px") + div(v-else style="height:20px;width:100%;display:flex;align-items:center;justify-content:center;color:rgb(144, 147, 153)") + span No Data span(style="display:block;margin-top:20px") {{ $t('view.favorite.avatars.local_favorites') }} br el-button(size="small" :disabled="!isLocalUserVrcplusSupporter()" @click="promptNewLocalAvatarFavoriteGroup") {{ $t('view.favorite.avatars.new_group') }} @@ -274,7 +295,7 @@ mixin favoritesTab() el-button(@click.stop="promptLocalAvatarFavoriteGroupRename(group)" size="mini" icon="el-icon-edit" circle style="margin-left:5px") el-tooltip(placement="right" :content="$t('view.favorite.delete_tooltip')" :disabled="hideTooltips") el-button(@click.stop="promptLocalAvatarFavoriteGroupDelete(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px") - .x-friend-list(style="margin-top:10px") + .x-friend-list(style="margin-top:10px" v-if="localAvatarFavorites[group].length") div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in localAvatarFavorites[group]" :key="favorite.id" @click="showAvatarDialog(favorite.id)") .x-friend-item template(v-if="favorite.name") @@ -301,3 +322,5 @@ mixin favoritesTab() .detail span(v-text="favorite.id") el-button(type="text" icon="el-icon-close" size="mini" @click.stop="removeLocalAvatarFavorite(favorite.id, group)" style="margin-left:5px") + div(v-else style="height:20px;width:100%;display:flex;align-items:center;justify-content:center;color:rgb(144, 147, 153)") + span No Data diff --git a/html/src/theme.dark.scss b/html/src/theme.dark.scss index 8e25398f..78268c9b 100644 --- a/html/src/theme.dark.scss +++ b/html/src/theme.dark.scss @@ -127,8 +127,9 @@ button { background-color: #333; } -.el-tag--plain.el-tag--success { +.el-collapse-item .el-tag--mini { background-color: #333; + border: transparent; } .el-button { diff --git a/html/src/theme.darkvanilla.scss b/html/src/theme.darkvanilla.scss index 1e25cc56..06aeeb35 100644 --- a/html/src/theme.darkvanilla.scss +++ b/html/src/theme.darkvanilla.scss @@ -687,3 +687,8 @@ i[class='el-icon-star-off']:not(.el-menu-item div.el-tooltip i) { .x-friend-item:hover .el-input__count { background-color: transparent; } + +.el-collapse-item .el-tag--mini { + border: transparent; + background-color: var(--dv_bg-bot); +} diff --git a/html/src/theme.darkvanillaold.scss b/html/src/theme.darkvanillaold.scss index b3c84f94..ff9a8f25 100644 --- a/html/src/theme.darkvanillaold.scss +++ b/html/src/theme.darkvanillaold.scss @@ -313,3 +313,8 @@ path[stroke='#20a0ff'] { path[stroke='#e5e9f2'] { stroke: var(--farback) !important; } + +.el-collapse-item .el-tag--mini { + border: transparent; + background-color: #333 !important; +} diff --git a/html/src/theme.material3.scss b/html/src/theme.material3.scss index c1569ab9..9576b210 100644 --- a/html/src/theme.material3.scss +++ b/html/src/theme.material3.scss @@ -1993,3 +1993,8 @@ i.x-user-status { .el-table_41_column_291 { text-align: center !important; } + +.el-collapse-item .el-tag--mini { + background-color: transparent; + border: transparent; +} diff --git a/html/src/theme.pink.scss b/html/src/theme.pink.scss index b3ababe6..40e6d8d1 100644 --- a/html/src/theme.pink.scss +++ b/html/src/theme.pink.scss @@ -361,3 +361,8 @@ input[type='checkbox']:checked + .el-switch__core { .x-friend-item:hover .el-input__count { background-color: var(--lighter-lighter-bg); } + +.el-collapse-item .el-tag--mini { + border: transparent; + background-color: #333; +}