diff --git a/html/src/app.js b/html/src/app.js
index d127d04a..05f8f1aa 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -5712,11 +5712,15 @@ speechSynthesis.getVoices();
);
}
if (this.saveCredentials) {
- savedCredentials[currentUser.username].loginParmas =
- this.saveCredentials;
+ var credentialsToSave = {
+ user: currentUser,
+ loginParmas: this.saveCredentials
+ };
+ savedCredentials[currentUser.username] = credentialsToSave;
delete this.saveCredentials;
- }
- if (typeof savedCredentials[currentUser.username] !== 'undefined') {
+ } else if (
+ typeof savedCredentials[currentUser.username] !== 'undefined'
+ ) {
savedCredentials[currentUser.username].user = currentUser;
savedCredentials[currentUser.username].cookies =
await webApiService.getCookies();
@@ -11449,9 +11453,6 @@ speechSynthesis.getVoices();
case 'Rename':
this.promptRenameWorld(D);
break;
- case 'Upload Image':
- document.getElementById('WorldImageUploadButton').click();
- break;
case 'Change Image':
this.displayPreviousImages('World', 'Change');
break;
@@ -11461,6 +11462,9 @@ speechSynthesis.getVoices();
case 'Change Description':
this.promptChangeWorldDescription(D);
break;
+ case 'Download Unity Package':
+ this.openExternalLink(this.worldDialog.ref.unityPackageUrl);
+ break;
default:
this.$confirm(`Continue? ${command}`, 'Confirm', {
confirmButtonText: 'Confirm',
@@ -11657,9 +11661,6 @@ speechSynthesis.getVoices();
case 'Rename':
this.promptRenameAvatar(D);
break;
- case 'Upload Image':
- document.getElementById('AvatarImageUploadButton').click();
- break;
case 'Change Image':
this.displayPreviousImages('Avatar', 'Change');
break;
@@ -12539,6 +12540,12 @@ speechSynthesis.getVoices();
});
$app.methods.setVRCPlusIcon = function (fileId) {
+ if (!API.currentUser.$isVRCPlus) {
+ this.$message({
+ message: 'VRCPlus required',
+ type: 'error'
+ });
+ }
var userIcon = '';
if (fileId) {
userIcon = `https://api.vrchat.cloud/api/1/file/${fileId}/1`;
@@ -12587,6 +12594,18 @@ speechSynthesis.getVoices();
});
};
+ API.deleteFileVersion = function (params) {
+ return this.call(`file/${params.fileId}/${params.version}`, {
+ method: 'DELETE'
+ }).then((json) => {
+ var args = {
+ json,
+ params
+ };
+ return args;
+ });
+ };
+
$app.methods.compareCurrentVRCPlusIcon = function (userIcon) {
var currentUserIcon = extractFileId(API.currentUser.userIcon);
if (userIcon === currentUserIcon) {
@@ -13613,6 +13632,7 @@ speechSynthesis.getVoices();
return;
}
this.avatarDialog.loading = true;
+ this.changeAvatarImageDialogLoading = true;
var r = new FileReader();
r.onload = async function (file) {
var base64File = btoa(r.result);
@@ -13688,6 +13708,7 @@ speechSynthesis.getVoices();
method: 'PUT'
});
$app.avatarDialog.loading = false;
+ $app.changeAvatarImageDialogLoading = false;
};
API.$on('AVATARIMAGE:INIT', function (args) {
@@ -13748,6 +13769,7 @@ speechSynthesis.getVoices();
.then((json) => {
if (json.status !== 200) {
$app.avatarDialog.loading = false;
+ $app.changeAvatarImageDialogLoading = false;
this.$throw('Avatar image upload failed', json);
}
var args = {
@@ -13844,6 +13866,7 @@ speechSynthesis.getVoices();
.then((json) => {
if (json.status !== 200) {
$app.avatarDialog.loading = false;
+ $app.changeAvatarImageDialogLoading = false;
this.$throw('Avatar image upload failed', json);
}
var args = {
@@ -13943,6 +13966,7 @@ speechSynthesis.getVoices();
return;
}
this.worldDialog.loading = true;
+ this.changeWorldImageDialogLoading = true;
var r = new FileReader();
r.onload = async function (file) {
var base64File = btoa(r.result);
@@ -14018,6 +14042,7 @@ speechSynthesis.getVoices();
method: 'PUT'
});
$app.worldDialog.loading = false;
+ $app.changeWorldImageDialogLoading = false;
};
API.$on('WORLDIMAGE:INIT', function (args) {
@@ -14078,6 +14103,7 @@ speechSynthesis.getVoices();
.then((json) => {
if (json.status !== 200) {
$app.worldDialog.loading = false;
+ $app.changeWorldImageDialogLoading = false;
this.$throw('World image upload failed', json);
}
var args = {
@@ -14174,6 +14200,7 @@ speechSynthesis.getVoices();
.then((json) => {
if (json.status !== 200) {
$app.worldDialog.loading = false;
+ $app.changeWorldImageDialogLoading = false;
this.$throw('World image upload failed', json);
}
var args = {
@@ -14240,11 +14267,13 @@ speechSynthesis.getVoices();
API.$on('AVATARIMAGE:SET', function (args) {
$app.avatarDialog.loading = false;
+ $app.changeAvatarImageDialogLoading = false;
if (args.json.imageUrl === args.params.imageUrl) {
$app.$message({
message: 'Avatar image changed',
type: 'success'
});
+ $app.displayPreviousImages('Avatar', 'Change');
} else {
this.$throw(0, 'Avatar image change failed');
}
@@ -14267,11 +14296,13 @@ speechSynthesis.getVoices();
API.$on('WORLDIMAGE:SET', function (args) {
$app.worldDialog.loading = false;
+ $app.changeWorldImageDialogLoading = false;
if (args.json.imageUrl === args.params.imageUrl) {
$app.$message({
message: 'World image changed',
type: 'success'
});
+ $app.displayPreviousImages('World', 'Change');
} else {
this.$throw(0, 'World image change failed');
}
@@ -14312,7 +14343,12 @@ speechSynthesis.getVoices();
}
API.getAvatarImages(params).then((args) => {
this.previousImagesTableFileId = args.json.id;
- var images = args.json.versions.reverse();
+ var images = [];
+ args.json.versions.forEach((item) => {
+ if (!item.deleted) {
+ images.unshift(item);
+ }
+ });
this.checkPreviousImageAvailable(images);
});
} else if (type === 'World') {
@@ -14324,13 +14360,23 @@ speechSynthesis.getVoices();
}
API.getWorldImages(params).then((args) => {
this.previousImagesTableFileId = args.json.id;
- var images = args.json.versions.reverse();
+ var images = [];
+ args.json.versions.forEach((item) => {
+ if (!item.deleted) {
+ images.unshift(item);
+ }
+ });
this.checkPreviousImageAvailable(images);
});
} else if (type === 'User') {
API.getAvatarImages(params).then((args) => {
this.previousImagesTableFileId = args.json.id;
- var images = args.json.versions.reverse();
+ var images = [];
+ args.json.versions.forEach((item) => {
+ if (!item.deleted) {
+ images.unshift(item);
+ }
+ });
this.checkPreviousImageAvailable(images);
});
}
@@ -14430,6 +14476,32 @@ speechSynthesis.getVoices();
});
};
+ $app.methods.uploadAvatarImage = function () {
+ document.getElementById('AvatarImageUploadButton').click();
+ };
+
+ $app.methods.deleteAvatarImage = function () {
+ this.changeAvatarImageDialogLoading = true;
+ var parmas = {
+ fileId: this.previousImagesTableFileId,
+ version: this.previousImagesTable[0].version
+ };
+ API.deleteFileVersion(parmas)
+ .then((args) => {
+ this.previousImagesTableFileId = args.json.id;
+ var images = [];
+ args.json.versions.forEach((item) => {
+ if (!item.deleted) {
+ images.unshift(item);
+ }
+ });
+ this.checkPreviousImageAvailable(images);
+ })
+ .finally(() => {
+ this.changeAvatarImageDialogLoading = false;
+ });
+ };
+
$app.methods.setWorldImage = function (image) {
this.changeWorldImageDialogLoading = true;
var parmas = {
@@ -14442,6 +14514,32 @@ speechSynthesis.getVoices();
});
};
+ $app.methods.uploadWorldImage = function () {
+ document.getElementById('WorldImageUploadButton').click();
+ };
+
+ $app.methods.deleteWorldImage = function () {
+ this.changeWorldImageDialogLoading = true;
+ var parmas = {
+ fileId: this.previousImagesTableFileId,
+ version: this.previousImagesTable[0].version
+ };
+ API.deleteFileVersion(parmas)
+ .then((args) => {
+ this.previousImagesTableFileId = args.json.id;
+ var images = [];
+ args.json.versions.forEach((item) => {
+ if (!item.deleted) {
+ images.unshift(item);
+ }
+ });
+ this.checkPreviousImageAvailable(images);
+ })
+ .finally(() => {
+ this.changeWorldImageDialogLoading = false;
+ });
+ };
+
$app.methods.compareCurrentImage = function (image) {
if (
`https://api.vrchat.cloud/api/1/file/${this.previousImagesTableFileId}/${image.version}/file` ===
@@ -15497,6 +15595,12 @@ speechSynthesis.getVoices();
});
$app.methods.setProfilePicOverride = function (fileId) {
+ if (!API.currentUser.$isVRCPlus) {
+ this.$message({
+ message: 'VRCPlus required',
+ type: 'error'
+ });
+ }
var profilePicOverride = '';
if (fileId) {
profilePicOverride = `https://api.vrchat.cloud/api/1/file/${fileId}/1`;
@@ -15910,7 +16014,6 @@ speechSynthesis.getVoices();
key !== API.currentUser.id
) {
API.cachedUsers.delete(key);
- console.log(key);
}
});
API.cachedWorlds.forEach((value, key) => {
@@ -15919,7 +16022,6 @@ speechSynthesis.getVoices();
value.authorId !== API.currentUser.id
) {
API.cachedWorlds.delete(key);
- console.log(key);
}
});
API.cachedAvatars.forEach((value, key) => {
@@ -15928,7 +16030,6 @@ speechSynthesis.getVoices();
value.authorId !== API.currentUser.id
) {
API.cachedAvatars.delete(key);
- console.log(key);
}
});
diff --git a/html/src/index.pug b/html/src/index.pug
index 4d95e3d2..e0a4eec4 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -1125,11 +1125,11 @@ html
div(v-loading="userDialog.loading")
div(style="display:flex")
el-popover(v-if="userDialog.ref.profilePicOverride" placement="right" width="500px" trigger="click")
- img.x-link(slot="reference" v-lazy="userDialog.ref.profilePicOverride" style="flex:none;width:160px;height:120px;border-radius:4px;object-fit:cover")
- img.x-link(v-lazy="userDialog.ref.profilePicOverride" style="width:500px;height:375px;object-fit:cover" @click="openExternalLink(userDialog.ref.profilePicOverride)")
+ img.x-link(slot="reference" v-lazy="userDialog.ref.profilePicOverride" style="flex:none;height:120px;width:213.33px;border-radius:4px;object-fit:cover")
+ img.x-link(v-lazy="userDialog.ref.profilePicOverride" style="height:400px" @click="openExternalLink(userDialog.ref.profilePicOverride)")
el-popover(v-else placement="right" width="500px" trigger="click")
- img.x-link(slot="reference" v-lazy="userDialog.ref.currentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
- img.x-link(v-lazy="userDialog.ref.currentAvatarImageUrl" style="width:500px;height:375px" @click="openExternalLink(userDialog.ref.currentAvatarImageUrl)")
+ img.x-link(slot="reference" v-lazy="userDialog.ref.currentAvatarThumbnailImageUrl" style="flex:none;height:120px;width:160px;border-radius:4px;object-fit:cover")
+ img.x-link(v-lazy="userDialog.ref.currentAvatarImageUrl" style="height:500px" @click="openExternalLink(userDialog.ref.currentAvatarImageUrl)")
div(style="flex:1;display:flex;align-items:center;margin-left:15px")
div(style="flex:1")
div
@@ -1163,8 +1163,8 @@ html
span(v-text="userDialog.ref.statusDescription" style="font-size:12px")
div(v-if="userDialog.ref.userIcon" style="flex:none;margin-right:10px")
el-popover(placement="right" width="500px" trigger="click")
- img.x-link(slot="reference" v-lazy="userDialog.ref.userIcon" style="flex:none;width:120px;height:120px;border-radius:4px")
- img.x-link(v-lazy="userDialog.ref.userIcon" style="width:500px;height:500px;" @click="openExternalLink(userDialog.ref.userIcon)")
+ img.x-link(slot="reference" v-lazy="userDialog.ref.userIcon" style="flex:none;width:120px;height:120px;border-radius:4px;object-fit:cover")
+ img.x-link(v-lazy="userDialog.ref.userIcon" style="height:500px" @click="openExternalLink(userDialog.ref.userIcon)")
div(style="flex:none")
el-tooltip(v-if="userDialog.isFavorite" placement="top" content="Remove from favorites" :disabled="hideTooltips")
el-button(@click="userDialogCommand('Delete Favorite')" type="warning" icon="el-icon-star-on" circle)
@@ -1399,8 +1399,7 @@ html
el-dropdown-item(icon="el-icon-edit" command="Rename") Rename
el-dropdown-item(icon="el-icon-edit" command="Change Description") Change Description
el-dropdown-item(icon="el-icon-picture-outline" command="Change Image") Change Image
- el-dropdown-item(icon="el-icon-upload2" command="Upload Image") Upload Image (1200x900)
- input(type="file" accept="image/*" @change="onFileChangeWorldImage" id="WorldImageUploadButton" style="display:none")
+ el-dropdown-item(v-if="worldDialog.ref.unityPackageUrl" icon="el-icon-download" command="Download Unity Package") Download Unity Package
el-dropdown-item(icon="el-icon-delete" command="Delete" style="color:#F56C6C" divided) Delete
el-tabs
el-tab-pane(label="Instances")
@@ -1548,8 +1547,6 @@ html
el-dropdown-item(icon="el-icon-edit" command="Rename") Rename
el-dropdown-item(icon="el-icon-edit" command="Change Description") Change Description
el-dropdown-item(icon="el-icon-picture-outline" command="Change Image") Change Image
- el-dropdown-item(icon="el-icon-upload2" command="Upload Image") Upload Image (1200x900)
- input(type="file" accept="image/*" @change="onFileChangeAvatarImage" id="AvatarImageUploadButton" style="display:none")
el-dropdown-item(v-if="avatarDialog.ref.unityPackageUrl" icon="el-icon-download" command="Download Unity Package") Download Unity Package
el-dropdown-item(icon="el-icon-user" command="Delete" style="color:#F56C6C" divided) Delete
el-tabs
@@ -2363,6 +2360,12 @@ html
//- dialog: Change avatar image
el-dialog.x-dialog(ref="changeAvatarImageDialog" :visible.sync="changeAvatarImageDialogVisible" title="Change Avatar Image" width="800px")
div(v-loading="changeAvatarImageDialogLoading")
+ input(type="file" accept="image/*" @change="onFileChangeAvatarImage" id="AvatarImageUploadButton" style="display:none")
+ el-button-group(style="padding-bottom:10px")
+ el-button(type="default" size="small" @click="displayPreviousImages('Avatar', 'Change')" icon="el-icon-refresh") Refresh
+ el-button(type="default" size="small" @click="uploadAvatarImage" icon="el-icon-upload2") Upload Image (1200x900)
+ //- el-button(type="default" size="small" @click="deleteAvatarImage" icon="el-icon-delete") Delete Latest Image
+ br
div(style="display:inline-block" v-for="image in previousImagesTable" :key="image.version" v-if="image.file")
.x-change-image-item(@click="setAvatarImage(image)" style="cursor:pointer" :class="{ 'current-image': compareCurrentImage(image) }")
img.image(v-lazy="image.file.url")
@@ -2370,6 +2373,12 @@ html
//- dialog: Change world image
el-dialog.x-dialog(ref="changeWorldImageDialog" :visible.sync="changeWorldImageDialogVisible" title="Change World Image" width="800px")
div(v-loading="changeWorldImageDialogLoading")
+ input(type="file" accept="image/*" @change="onFileChangeWorldImage" id="WorldImageUploadButton" style="display:none")
+ el-button-group(style="padding-bottom:10px")
+ el-button(type="default" size="small" @click="displayPreviousImages('World', 'Change')" icon="el-icon-refresh") Refresh
+ el-button(type="default" size="small" @click="uploadWorldImage" icon="el-icon-upload2") Upload Image (1200x900)
+ //- el-button(type="default" size="small" @click="deleteWorldImage" icon="el-icon-delete") Delete Latest Image
+ br
div(style="display:inline-block" v-for="image in previousImagesTable" :key="image.version" v-if="image.file")
.x-change-image-item(@click="setWorldImage(image)" style="cursor:pointer" :class="{ 'current-image': compareCurrentImage(image) }")
img.image(v-lazy="image.file.url")