diff --git a/html/src/app.js b/html/src/app.js index a16f8016..0fef5236 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -1868,27 +1868,6 @@ speechSynthesis.getVoices(); }); }; - /* - params: { - avatarId: string - } - */ - API.getCachedAvatar = function (params) { - return new Promise((resolve, reject) => { - var ref = this.cachedAvatars.get(params.avatarId); - if (typeof ref === 'undefined') { - this.getAvatar(params).catch(reject).then(resolve); - } else { - resolve({ - cache: true, - json: ref, - params, - ref - }); - } - }); - }; - /* params: { n: number, @@ -8565,48 +8544,44 @@ speechSynthesis.getVoices(); this.$nextTick(() => adjustDialogZ(this.$refs.avatarDialog.$el)); var D = this.avatarDialog; D.id = avatarId; + var ref = API.cachedAvatars.get(avatarId); + if (!ref) { + D.visible = false; + this.$message({ + message: 'Avatar cache unavailable', + type: 'error' + }); + return; + } D.treeData = []; D.fileSize = 'Unknown'; D.visible = true; - D.loading = true; - API.getCachedAvatar({ - avatarId - }).catch((err) => { - D.loading = false; - D.visible = false; - throw err; - }).then((args) => { - if ((D.visible) && (D.id === args.ref.id)) { - D.loading = false; - D.ref = args.ref; - D.isFavorite = API.cachedFavoritesByObjectId.has(D.ref.id); - if ((args.cache) && (D.ref.authorId === API.currentUser.id)) { - API.getAvatar(args.params); + D.ref = ref; + D.isFavorite = API.cachedFavoritesByObjectId.has(avatarId); + if (D.ref.authorId === API.currentUser.id) { + API.getAvatar({avatarId}); + } else { + var id = extractFileId(D.ref.assetUrl); + var fileId = extractFileId(D.ref.imageUrl); + if (id) { + D.fileSize = 'Loading'; + API.call(`file/${id}`).then((json) => { + var fileRef = json.versions[json.versions.length - 1]; + D.ref.created_at = fileRef.created_at; + D.fileSize = `${(fileRef.file.sizeInBytes / 1048576).toFixed(2)} MiB`; + }); + } else if ((fileId) && (!D.ref.created_at)) { + if (API.cachedAvatarNames.has(fileId)) { + var avatarInfo = API.cachedAvatarNames.get(fileId); + D.ref.created_at = avatarInfo.fileCreatedAt; } else { - var id = extractFileId(args.ref.assetUrl); - var fileId = extractFileId(D.ref.imageUrl); - if (id) { - D.fileSize = 'Loading'; - API.call(`file/${id}`).then((json) => { - var ref = json.versions[json.versions.length - 1]; - D.ref.created_at = ref.created_at; - D.fileSize = `${(ref.file.sizeInBytes / 1048576).toFixed(2)} MiB`; - }); - } else if ((fileId) && (!D.ref.created_at)) { - if (API.cachedAvatarNames.has(fileId)) { - var avatarInfo = API.cachedAvatarNames.get(fileId); - D.ref.created_at = avatarInfo.fileCreatedAt; - } else { - API.getAvatarImages({fileId}).then((args) => { - var avatarInfo = this.storeAvatarImage(args); - D.ref.created_at = avatarInfo.fileCreatedAt; - }); - } - } + API.getAvatarImages({fileId}).then((args) => { + var avatarInfo = this.storeAvatarImage(args); + D.ref.created_at = avatarInfo.fileCreatedAt; + }); } } - return args; - }); + } }; $app.methods.avatarDialogCommand = function (command) { @@ -8824,6 +8799,18 @@ speechSynthesis.getVoices(); }); }; + $app.methods.moveFavorite = function (ref, group, type) { + API.deleteFavorite({ + objectId: ref.id + }).then(() => { + API.addFavorite({ + type, + favoriteId: ref.id, + tags: group.name + }); + }); + }; + $app.methods.showFavoriteDialog = function (type, objectId) { this.$nextTick(() => adjustDialogZ(this.$refs.favoriteDialog.$el)); var D = this.favoriteDialog; diff --git a/html/src/index.pug b/html/src/index.pug index 13abb28c..3dc62d6b 100644 --- a/html/src/index.pug +++ b/html/src/index.pug @@ -262,18 +262,31 @@ html el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px") 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") - .x-friend-item(v-for="favorite in favoriteFriends" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showUserDialog(favorite.id)") - template(v-if="favorite.ref") - .avatar(:class="userStatusClass(favorite.ref)") - img(v-if="displayVRCPlusIconsAsAvatar && favorite.ref.userIcon" v-lazy="favorite.ref.userIcon") - img(v-else v-lazy="favorite.ref.currentAvatarThumbnailImageUrl") - .detail - span.name(v-text="favorite.ref.displayName" :class="favorite.ref.$trustClass") - location.extra(v-if="favorite.ref.location !== 'offline'" :location="favorite.ref.location" :link="false") - span(v-else v-text="favorite.ref.statusDescription") - template(v-else) - 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(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteFriends" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showUserDialog(favorite.id)") + .x-friend-item + template(v-if="favorite.ref") + .avatar(:class="userStatusClass(favorite.ref)") + img(v-if="displayVRCPlusIconsAsAvatar && favorite.ref.userIcon" v-lazy="favorite.ref.userIcon") + img(v-else v-lazy="favorite.ref.currentAvatarThumbnailImageUrl") + .detail + span.name(v-text="favorite.ref.displayName" :class="favorite.ref.$trustClass") + location.extra(v-if="favorite.ref.location !== 'offline'" :location="favorite.ref.location" :link="false") + span(v-else v-text="favorite.ref.statusDescription") + el-tooltip(placement="left") + template(#content) + span Move + el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px") + el-button(type="default" icon="el-icon-back" size="mini" circle) + el-dropdown-menu(#default="dropdown") + template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'friend')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }}) + el-tooltip(placement="right") + template(#content) + span Unfavorite + el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px") + template(v-else) + 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") el-tab-pane(label="World") el-collapse(style="border:0") el-collapse-item(v-for="group in API.favoriteWorldGroups" :key="group.name") @@ -283,36 +296,66 @@ html el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px") 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") - .x-friend-item(v-for="favorite in favoriteWorlds" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showWorldDialog(favorite.id)") - template(v-if="favorite.ref") - .avatar - img(v-lazy="favorite.ref.thumbnailImageUrl") - .detail - span.name(v-text="favorite.ref.name") - span.extra(v-if="favorite.ref.occupants") {{ favorite.ref.authorName }} ({{ favorite.ref.occupants }}) - span.extra(v-else v-text="favorite.ref.authorName") - template(v-else) - 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(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 + template(v-if="favorite.ref") + .avatar + img(v-lazy="favorite.ref.thumbnailImageUrl") + .detail + span.name(v-text="favorite.ref.name") + span.extra(v-if="favorite.ref.occupants") {{ favorite.ref.authorName }} ({{ favorite.ref.occupants }}) + span.extra(v-else v-text="favorite.ref.authorName") + el-tooltip(placement="left") + template(#content) + span Move + el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px") + el-button(type="default" icon="el-icon-back" size="mini" circle) + el-dropdown-menu(#default="dropdown") + template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteWorldGroups" :key="groupAPI.name") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'world')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }}) + el-tooltip(placement="right") + template(#content) + span Unfavorite + el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px") + template(v-else) + 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") el-tab-pane(label="Avatar") + el-tooltip(placement="top") + template(#content) + span Add favorite + el-button(style="margin-left:5px" icon="el-icon-plus" size="small" @click="promptAddAvatarFavoriteDialog" circle) el-collapse(style="border:0") el-collapse-item(v-for="group in API.favoriteAvatarGroups" :key="group.name") template(slot="title") span(v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px") span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }} - //- el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px") 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") - .x-friend-item(v-for="favorite in favoriteAvatars" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showAvatarDialog(favorite.id)") - template(v-if="favorite.ref") - .avatar - img(v-lazy="favorite.ref.thumbnailImageUrl") - .detail - span.name(v-text="favorite.ref.name") - span.extra(v-text="favorite.ref.authorName") - template(v-else) - 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(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteAvatars" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showAvatarDialog(favorite.id)") + .x-friend-item + template(v-if="favorite.ref") + .avatar + img(v-lazy="favorite.ref.thumbnailImageUrl") + .detail + span.name(v-text="favorite.ref.name") + span.extra(v-text="favorite.ref.authorName") + el-tooltip(placement="left") + template(#content) + span Move + el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px") + el-button(type="default" icon="el-icon-back" size="mini" circle) + el-dropdown-menu(#default="dropdown") + template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteAvatarGroups" :key="groupAPI.name") + el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'avatar')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }}) + el-tooltip(placement="right") + template(#content) + span Unfavorite + el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px") + template(v-else) + .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") //- friendLog .x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'friendLog'") @@ -1085,15 +1128,14 @@ html el-tab-pane(label="Avatars") template(v-if="userDialog.ref.id === API.currentUser.id") el-button(type="default" :loading="userDialog.isAvatarsLoading" @click="refreshUserDialogAvatars()" size="mini" icon="el-icon-refresh" circle) - template(v-if="userDialogAvatars.length > 0") - span(style="margin-left:5px") Total {{ userDialogAvatars.length }} - el-radio-group(v-model="userDialog.avatarSorting" size="mini" style="margin-left:30px" @change="changeUserDialogAvatarSorting") - el-radio(label="name") by name - el-radio(label="update") by update - el-radio-group(v-model="userDialog.avatarReleaseStatus" size="mini" style="margin-left:60px") - el-radio(label="all") all - el-radio(label="public") public - el-radio(label="private") private + span(style="margin-left:5px") Total {{ userDialogAvatars.length }} + el-radio-group(v-model="userDialog.avatarSorting" size="mini" style="margin-left:30px" @change="changeUserDialogAvatarSorting") + el-radio(label="name") by name + el-radio(label="update") by update + el-radio-group(v-model="userDialog.avatarReleaseStatus" size="mini" style="margin-left:60px") + el-radio(label="all") all + el-radio(label="public") public + el-radio(label="private") private .x-friend-list(v-loading="userDialog.isAvatarsLoading" style="margin-top:10px;min-height:60px") .x-friend-item(v-for="avatar in userDialogAvatars" :key="avatar.id" @click="showAvatarDialog(avatar.id)") .avatar @@ -1296,7 +1338,7 @@ html span(v-if="!scope.data.children" v-text="scope.data.value") //- dialog: favorite - el-dialog.x-dialog(ref="favoriteDialog" :visible.sync="favoriteDialog.visible" title="Choose Group" width="250px") + el-dialog.x-dialog(ref="favoriteDialog" :visible.sync="favoriteDialog.visible" title="Choose Group" width="300px") div(v-loading="favoriteDialog.loading") el-button(v-for="group in favoriteDialog.groups" :key="group.name" style="display:block;width:100%;margin:10px 0" @click="addFavorite(group)" :disabled="group.count >= group.capacity") {{ group.displayName }} ({{ group.count }} / {{ group.capacity }})