Add changing avatar image to a previous one and display avatar names

This commit is contained in:
Natsumi
2021-04-03 13:59:12 +13:00
parent 816d9749a3
commit c473432de8
4 changed files with 198 additions and 48 deletions
+2 -1
View File
@@ -308,7 +308,8 @@ button {
color: #fff; color: #fff;
} }
.x-friend-item:hover { .x-friend-item:hover,
.x-change-avatar-item:hover {
background: #3e3e3e; background: #3e3e3e;
} }
+159 -46
View File
@@ -7265,7 +7265,11 @@ speechSynthesis.getVoices();
avatarReleaseStatus: 'all', avatarReleaseStatus: 'all',
treeData: [], treeData: [],
memo: '' memo: '',
$avatarInfo: {
id: '',
name: '',
}
}; };
$app.watch['userDialog.memo'] = function () { $app.watch['userDialog.memo'] = function () {
@@ -7508,6 +7512,7 @@ speechSynthesis.getVoices();
if (args.cache) { if (args.cache) {
API.getUser(args.params); API.getUser(args.params);
} }
this.getAvatarName(args);
} }
return args; return args;
}); });
@@ -8364,6 +8369,9 @@ speechSynthesis.getVoices();
case 'Upload Image': case 'Upload Image':
document.getElementById('AvatarImageUploadButton').click(); document.getElementById('AvatarImageUploadButton').click();
break; break;
case 'Change Image':
this.displayAvatarImages();
break;
case 'Change Description': case 'Change Description':
this.promptChangeDescription(D); this.promptChangeDescription(D);
break; break;
@@ -9980,6 +9988,8 @@ speechSynthesis.getVoices();
return response; return response;
}; };
// Upload avatar image
$app.methods.onFileChangeAvatarImage = function (e) { $app.methods.onFileChangeAvatarImage = function (e) {
var clearFile = function () { var clearFile = function () {
if (document.querySelector('#AvatarImageUploadButton')) { if (document.querySelector('#AvatarImageUploadButton')) {
@@ -10041,19 +10051,6 @@ speechSynthesis.getVoices();
clearFile(); clearFile();
}; };
API.getAvatarImages = function (params) {
return this.call(`file/${params.fileId}`, {
method: 'GET',
params
}).then((json) => {
var args = {
json,
params
};
return args;
});
};
API.uploadAvatarImage = async function (params, fileId) { API.uploadAvatarImage = async function (params, fileId) {
try { try {
return await this.call(`file/${fileId}`, { return await this.call(`file/${fileId}`, {
@@ -10064,7 +10061,7 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE1', args); this.$emit('AVATARIMAGE:INIT', args);
return args; return args;
}); });
} catch (err) { } catch (err) {
@@ -10074,7 +10071,7 @@ speechSynthesis.getVoices();
}; };
API.uploadAvatarFailCleanup = async function (fileId) { API.uploadAvatarFailCleanup = async function (fileId) {
var args = await this.call(`file/${fileId}`, { var json = await this.call(`file/${fileId}`, {
method: 'GET' method: 'GET'
}).then((json) => { }).then((json) => {
return json; return json;
@@ -10090,17 +10087,17 @@ speechSynthesis.getVoices();
$app.avatarDialog.loading = false; $app.avatarDialog.loading = false;
}; };
API.$on('AVATARIMAGE:STAGE1', function (args) { API.$on('AVATARIMAGE:INIT', function (args) {
var fileId = args.json.id; var fileId = args.json.id;
var fileVersion = args.json.versions[args.json.versions.length - 1].version; var fileVersion = args.json.versions[args.json.versions.length - 1].version;
var params = { var params = {
fileId, fileId,
fileVersion fileVersion
}; };
this.uploadAvatarImageStage2(params); this.uploadAvatarImageFileStart(params);
}); });
API.uploadAvatarImageStage2 = async function (params) { API.uploadAvatarImageFileStart = async function (params) {
try { try {
return await this.call(`file/${params.fileId}/${params.fileVersion}/file/start`, { return await this.call(`file/${params.fileId}/${params.fileVersion}/file/start`, {
method: 'PUT' method: 'PUT'
@@ -10109,7 +10106,7 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE2', args); this.$emit('AVATARIMAGE:FILESTART', args);
return args; return args;
}); });
} catch (err) { } catch (err) {
@@ -10118,7 +10115,7 @@ speechSynthesis.getVoices();
} }
}; };
API.$on('AVATARIMAGE:STAGE2', function (args) { API.$on('AVATARIMAGE:FILESTART', function (args) {
var { url } = args.json; var { url } = args.json;
var { fileId, fileVersion } = args.params; var { fileId, fileVersion } = args.params;
var params = { var params = {
@@ -10126,10 +10123,10 @@ speechSynthesis.getVoices();
fileId, fileId,
fileVersion fileVersion
}; };
this.uploadAvatarImageStage3(params); this.uploadAvatarImageFileAWS(params);
}); });
API.uploadAvatarImageStage3 = function (params) { API.uploadAvatarImageFileAWS = function (params) {
return webApiService.execute({ return webApiService.execute({
url: params.url, url: params.url,
uploadFilePUT: true, uploadFilePUT: true,
@@ -10147,21 +10144,21 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE3', args); this.$emit('AVATARIMAGE:FILEAWS', args);
return args; return args;
}); });
}; };
API.$on('AVATARIMAGE:STAGE3', function (args) { API.$on('AVATARIMAGE:FILEAWS', function (args) {
var { fileId, fileVersion } = args.params; var { fileId, fileVersion } = args.params;
var params = { var params = {
fileId, fileId,
fileVersion fileVersion
}; };
this.uploadAvatarImageStage4(params); this.uploadAvatarImageFileFinish(params);
}); });
API.uploadAvatarImageStage4 = function (params) { API.uploadAvatarImageFileFinish = function (params) {
return this.call(`file/${params.fileId}/${params.fileVersion}/file/finish`, { return this.call(`file/${params.fileId}/${params.fileVersion}/file/finish`, {
method: 'PUT', method: 'PUT',
params: { params: {
@@ -10173,21 +10170,21 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE4', args); this.$emit('AVATARIMAGE:FILEFINISH', args);
return args; return args;
}); });
}; };
API.$on('AVATARIMAGE:STAGE4', function (args) { API.$on('AVATARIMAGE:FILEFINISH', function (args) {
var { fileId, fileVersion } = args.params; var { fileId, fileVersion } = args.params;
var params = { var params = {
fileId, fileId,
fileVersion fileVersion
}; };
this.uploadAvatarImageStage5(params); this.uploadAvatarImageSigStart(params);
}); });
API.uploadAvatarImageStage5 = async function (params) { API.uploadAvatarImageSigStart = async function (params) {
try { try {
return await this.call(`file/${params.fileId}/${params.fileVersion}/signature/start`, { return await this.call(`file/${params.fileId}/${params.fileVersion}/signature/start`, {
method: 'PUT' method: 'PUT'
@@ -10196,7 +10193,7 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE5', args); this.$emit('AVATARIMAGE:SIGSTART', args);
return args; return args;
}); });
} catch (err) { } catch (err) {
@@ -10205,7 +10202,7 @@ speechSynthesis.getVoices();
} }
}; };
API.$on('AVATARIMAGE:STAGE5', function (args) { API.$on('AVATARIMAGE:SIGSTART', function (args) {
var { url } = args.json; var { url } = args.json;
var { fileId, fileVersion } = args.params; var { fileId, fileVersion } = args.params;
var params = { var params = {
@@ -10213,10 +10210,10 @@ speechSynthesis.getVoices();
fileId, fileId,
fileVersion fileVersion
}; };
this.uploadAvatarImageStage6(params); this.uploadAvatarImageSigAWS(params);
}); });
API.uploadAvatarImageStage6 = function (params) { API.uploadAvatarImageSigAWS = function (params) {
return webApiService.execute({ return webApiService.execute({
url: params.url, url: params.url,
uploadFilePUT: true, uploadFilePUT: true,
@@ -10234,21 +10231,21 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE6', args); this.$emit('AVATARIMAGE:SIGAWS', args);
return args; return args;
}); });
}; };
API.$on('AVATARIMAGE:STAGE6', function (args) { API.$on('AVATARIMAGE:SIGAWS', function (args) {
var { fileId, fileVersion } = args.params; var { fileId, fileVersion } = args.params;
var params = { var params = {
fileId, fileId,
fileVersion fileVersion
}; };
this.uploadAvatarImageStage7(params); this.uploadAvatarImageSigFinish(params);
}); });
API.uploadAvatarImageStage7 = function (params) { API.uploadAvatarImageSigFinish = function (params) {
return this.call(`file/${params.fileId}/${params.fileVersion}/signature/finish`, { return this.call(`file/${params.fileId}/${params.fileVersion}/signature/finish`, {
method: 'PUT', method: 'PUT',
params: { params: {
@@ -10260,21 +10257,21 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE7', args); this.$emit('AVATARIMAGE:SIGFINISH', args);
return args; return args;
}); });
}; };
API.$on('AVATARIMAGE:STAGE7', function (args) { API.$on('AVATARIMAGE:SIGFINISH', function (args) {
var { fileId, fileVersion } = args.params; var { fileId, fileVersion } = args.params;
var parmas = { var parmas = {
id: $app.avatarImage.avatarId, id: $app.avatarImage.avatarId,
imageUrl: `https://api.vrchat.cloud/api/1/file/${fileId}/${fileVersion}/file` imageUrl: `https://api.vrchat.cloud/api/1/file/${fileId}/${fileVersion}/file`
}; };
this.uploadAvatarImageStage8(parmas); this.setAvatarImage(parmas);
}); });
API.uploadAvatarImageStage8 = function (params) { API.setAvatarImage = function (params) {
return this.call(`avatars/${params.id}`, { return this.call(`avatars/${params.id}`, {
method: 'PUT', method: 'PUT',
params params
@@ -10283,17 +10280,17 @@ speechSynthesis.getVoices();
json, json,
params params
}; };
this.$emit('AVATARIMAGE:STAGE8', args); this.$emit('AVATARIMAGE:SET', args);
this.$emit('AVATAR', args); this.$emit('AVATAR', args);
return args; return args;
}); });
}; };
API.$on('AVATARIMAGE:STAGE8', function (args) { API.$on('AVATARIMAGE:SET', function (args) {
$app.avatarDialog.loading = false; $app.avatarDialog.loading = false;
if (args.json.imageUrl === args.params.imageUrl) { if (args.json.imageUrl === args.params.imageUrl) {
$app.$message({ $app.$message({
message: 'Avatar image uploaded', message: 'Avatar image changed',
type: 'success' type: 'success'
}); });
} else { } else {
@@ -10301,6 +10298,122 @@ speechSynthesis.getVoices();
} }
}); });
// Set avatar image
$app.methods.displayAvatarImages = function () {
this.changeAvatarImageTableFileId = '';
this.changeAvatarImageTable = '';
if (this.avatarDialog.visible) {
var { imageUrl } = this.avatarDialog.ref;
} else if (this.userDialog.visible) {
var imageUrl = this.userDialog.ref.currentAvatarImageUrl;
} else {
return;
}
var url = new URL(imageUrl);
var pathArray = url.pathname.split('/');
var fileId = pathArray[4];
var params = {
fileId
};
this.changeAvatarImageDialogVisible = true;
this.$nextTick(() => adjustDialogZ(this.$refs.changeAvatarImageDialog.$el));
API.getAvatarImages(params).then((args) => {
this.changeAvatarImageTableFileId = args.json.id;
var images = args.json.versions;
var imageArray = [];
images.forEach((image) => {
if (image.file) {
imageArray.push(image.file.url);
}
});
this.changeAvatarImageTable = images;
});
};
API.getAvatarImages = function (params) {
return this.call(`file/${params.fileId}`, {
method: 'GET',
params
}).then((json) => {
var args = {
json,
params
};
return args;
});
};
$app.methods.setAvatarImage = function (image) {
this.changeAvatarImageDialogLoading = true;
var parmas = {
id: $app.avatarDialog.id,
imageUrl: `https://api.vrchat.cloud/api/1/file/${$app.changeAvatarImageTableFileId}/${image.version}/file`
};
API.setAvatarImage(parmas).finally(() => {
this.changeAvatarImageDialogLoading = false;
$app.changeAvatarImageDialogVisible = false;
});
};
$app.methods.compareCurrentAvatarImage = function (image) {
if (`https://api.vrchat.cloud/api/1/file/${$app.changeAvatarImageTableFileId}/${image.version}/file` === this.avatarDialog.ref.imageUrl) {
return true;
}
return false;
}
$app.data.changeAvatarImageDialogVisible = false;
$app.data.changeAvatarImageDialogLoading = false;
$app.data.changeAvatarImageTable = {};
$app.data.changeAvatarImageTableFileId = '';
API.$on('LOGIN', function () {
$app.changeAvatarImageTable = {};
$app.changeAvatarImageDialogVisible = false;
});
// Avatar names
API.cachedAvatarNames = new Map();
$app.methods.getAvatarName = function (args) {
var D = this.userDialog;
if (!D.visible) {
return;
}
var imageUrl = D.ref.currentAvatarImageUrl;
var url = new URL(imageUrl);
var pathArray = url.pathname.split('/');
var fileId = pathArray[4];
if (API.cachedAvatarNames.has(fileId)) {
D.$avatarInfo = API.cachedAvatarNames.get(fileId);
return;
}
D.$avatarInfo = {
id: '',
name: ''
};
var params = {
fileId
};
API.getAvatarImages(params).then((args) => {
var name = '';
var imageName = args.json.name;
var avatarNameRegex = /Avatar - (.*) - Image -/g.exec(imageName);
if (avatarNameRegex[1]) {
name = avatarNameRegex[1];
}
var id = args.json.ownerId;
var avatarInfo = {
id,
name
};
API.cachedAvatarNames.set(fileId, avatarInfo);
D.$avatarInfo = avatarInfo;
});
};
$app = new Vue($app); $app = new Vue($app);
window.$app = $app; window.$app = $app;
}()); }());
+21
View File
@@ -385,6 +385,27 @@ img.friends-list-avatar {
object-fit: cover; object-fit: cover;
} }
.x-change-avatar-item {
cursor: pointer;
display: inline-block;
padding: 4px 4px 0 4px;
}
.x-change-avatar-item:hover {
background: #f0f0f0;
border-radius: 2px;
}
.x-change-avatar-item > img {
width: 240px;
height: 180px;
}
.current-avatar-image {
border: 2px solid #67c23a;
padding: 2px 2px 0 2px;
}
.x-dialog > .el-dialog { .x-dialog > .el-dialog {
max-width: 100%; max-width: 100%;
margin-bottom: 10px; margin-bottom: 10px;
+16 -1
View File
@@ -1012,7 +1012,14 @@ html
.x-friend-item(style="width:100%;cursor:default") .x-friend-item(style="width:100%;cursor:default")
.detail .detail
span.name Note span.name Note
el-input.extra(v-model="userDialog.memo" type="textarea" :rows="2" :autosize="{ minRows: 2, maxRows: 20 }" placeholder="Click to add a note" size="mini" resize="none") el-input.extra(v-model="userDialog.memo" type="textarea" :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" placeholder="Click to add a note" size="mini" resize="none")
.x-friend-item(style="width:100%;cursor:default")
.detail
span.name Avatar Name
div(@click="userDialogCommand('Show Avatar Details')" style="cursor:pointer;width:fit-content")
span.extra(v-text="userDialog.$avatarInfo.name" style="display:inline-block;margin-right:5px")
span.extra(v-if="userDialog.$avatarInfo.id === userDialog.id" style="display:inline-block;color:#E6A23C" ) (own)
span.extra(v-else-if="userDialog.$avatarInfo.name" style="display:inline-block;color:#67C23A") (public)
.x-friend-item(style="width:100%;cursor:default") .x-friend-item(style="width:100%;cursor:default")
.detail .detail
span.name Bio span.name Bio
@@ -1229,6 +1236,7 @@ html
el-dropdown-item(v-else icon="el-icon-user" command="Make Public" divided) Make Public el-dropdown-item(v-else icon="el-icon-user" command="Make Public" divided) Make Public
el-dropdown-item(icon="el-icon-edit" command="Rename") Rename 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-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 el-dropdown-item(icon="el-icon-upload2" command="Upload Image") Upload Image
input(type="file" multiple accept="image/*" @change="onFileChangeAvatarImage" id="AvatarImageUploadButton" style="display:none") input(type="file" multiple accept="image/*" @change="onFileChangeAvatarImage" id="AvatarImageUploadButton" style="display:none")
el-dropdown-item(icon="el-icon-user" command="Delete" style="color:#F56C6C" divided) Delete el-dropdown-item(icon="el-icon-user" command="Delete" style="color:#F56C6C" divided) Delete
@@ -1674,6 +1682,13 @@ html
template(#footer) template(#footer)
el-button(type="small" @click="cancelEditAndSendInvite") Cancel el-button(type="small" @click="cancelEditAndSendInvite") Cancel
el-button(type="primary" size="small" @click="saveEditAndSendInvite") Send el-button(type="primary" size="small" @click="saveEditAndSendInvite") Send
//- dialog: Change avatar image
el-dialog.x-dialog(ref="changeAvatarImageDialog" :visible.sync="changeAvatarImageDialogVisible" title="Change Avatar Image" width="800px")
div(v-loading="changeAvatarImageDialogLoading")
div(style="display:inline-block" v-for="image in changeAvatarImageTable" :key="image.version" v-if="image.file")
.x-change-avatar-item(@click="setAvatarImage(image)" :class="{ 'current-avatar-image': compareCurrentAvatarImage(image) }")
img.avatar(v-lazy="image.file.url")
//- dialog: open source software notice //- dialog: open source software notice
el-dialog.x-dialog(:visible.sync="ossDialog" title="Open Source Software Notice" width="650px") el-dialog.x-dialog(:visible.sync="ossDialog" title="Open Source Software Notice" width="650px")