Improve avatar selection on edit identity

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2020-10-25 12:01:50 +01:00
parent 4a11d4adcc
commit 0be3e0c9fa
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
2 changed files with 25 additions and 23 deletions

View file

@ -1,7 +1,7 @@
import { IPicture } from "@/types/picture.model"; import { IPicture } from "@/types/picture.model";
export async function buildFileFromIPicture(obj: IPicture | null | undefined) { export async function buildFileFromIPicture(obj: IPicture | null | undefined): Promise<File | null> {
if (!obj) return null; if (!obj) return Promise.resolve(null);
const response = await fetch(obj.url); const response = await fetch(obj.url);
const blob = await response.blob(); const blob = await response.blob();
@ -9,7 +9,7 @@ export async function buildFileFromIPicture(obj: IPicture | null | undefined) {
return new File([blob], obj.name); return new File([blob], obj.name);
} }
export function buildFileVariable<T>(file: File | null, name: string, alt?: string) { export function buildFileVariable<T>(file: File | null, name: string, alt?: string): Record<string, unknown> {
if (!file) return {}; if (!file) return {};
return { return {

View file

@ -27,7 +27,7 @@
<span v-else>{{ $t("I create an identity") }}</span> <span v-else>{{ $t("I create an identity") }}</span>
</h1> </h1>
<picture-upload v-model="avatarFile" class="picture-upload" /> <picture-upload v-model="avatarFile" :defaultImageSrc="avatarUrl" class="picture-upload" />
<b-field horizontal :label="$t('Display name')"> <b-field horizontal :label="$t('Display name')">
<b-input <b-input
@ -124,7 +124,6 @@ h1 {
<script lang="ts"> <script lang="ts">
import { Component, Prop, Watch } from "vue-property-decorator"; import { Component, Prop, Watch } from "vue-property-decorator";
import { mixins } from "vue-class-component"; import { mixins } from "vue-class-component";
import { Route } from "vue-router";
import { import {
CREATE_PERSON, CREATE_PERSON,
CURRENT_ACTOR_CLIENT, CURRENT_ACTOR_CLIENT,
@ -137,7 +136,7 @@ import { IPerson, Person } from "../../../types/actor";
import PictureUpload from "../../../components/PictureUpload.vue"; import PictureUpload from "../../../components/PictureUpload.vue";
import { MOBILIZON_INSTANCE_HOST } from "../../../api/_entrypoint"; import { MOBILIZON_INSTANCE_HOST } from "../../../api/_entrypoint";
import RouteName from "../../../router/name"; import RouteName from "../../../router/name";
import { buildFileFromIPicture, buildFileVariable, readFileAsync } from "../../../utils/image"; import { buildFileVariable } from "../../../utils/image";
import { changeIdentity } from "../../../utils/auth"; import { changeIdentity } from "../../../utils/auth";
import identityEditionMixin from "../../../mixins/identityEdition"; import identityEditionMixin from "../../../mixins/identityEdition";
@ -185,24 +184,31 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
return this.$t("Only alphanumeric characters and underscores are supported.") as string; return this.$t("Only alphanumeric characters and underscores are supported.") as string;
} }
get avatarUrl(): string | null {
if (this.identity && this.identity.avatar && this.identity.avatar.url) {
return this.identity.avatar.url;
}
return null;
}
@Watch("isUpdate") @Watch("isUpdate")
async isUpdateChanged(): Promise<void> { async isUpdateChanged(): Promise<void> {
this.resetFields(); this.resetFields();
} }
@Watch("identityName", { immediate: true }) @Watch("identityName", { immediate: true })
async onIdentityParamChanged(val: string): Promise<Route | undefined> { async onIdentityParamChanged(val: string): Promise<void> {
// Only used when we update the identity // Only used when we update the identity
if (!this.isUpdate) return; if (!this.isUpdate) return;
await this.redirectIfNoIdentitySelected(val); await this.redirectIfNoIdentitySelected(val);
if (!this.identityName) { if (!this.identityName) {
return this.$router.push({ name: "CreateIdentity" }); this.$router.push({ name: "CreateIdentity" });
} }
if (this.identityName && this.identity) { if (this.identityName && this.identity) {
this.avatarFile = await buildFileFromIPicture(this.identity.avatar); this.avatarFile = null;
} }
} }
@ -278,6 +284,7 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
} }
}, },
}); });
this.avatarFile = null;
this.$notifier.success( this.$notifier.success(
this.$t("Identity {displayName} updated", { this.$t("Identity {displayName} updated", {
@ -376,23 +383,18 @@ export default class EditIdentity extends mixins(identityEditionMixin) {
} }
private async buildVariables() { private async buildVariables() {
const avatarObj = buildFileVariable( /**
* We set the avatar only if user has selected one
*/
let avatarObj: Record<string, unknown> = { avatar: null };
if (this.avatarFile) {
avatarObj = buildFileVariable(
this.avatarFile, this.avatarFile,
"avatar", "avatar",
`${this.identity.preferredUsername}'s avatar` `${this.identity.preferredUsername}'s avatar`
); );
}
const res = { ...this.identity, ...avatarObj }; const res = { ...this.identity, ...avatarObj };
/**
* If the avatar didn't change, no need to try reuploading it
*/
if (this.identity.avatar) {
const oldAvatarFile = (await buildFileFromIPicture(this.identity.avatar)) as File;
const oldAvatarFileContent = await readFileAsync(oldAvatarFile);
const newAvatarFileContent = await readFileAsync(this.avatarFile as File);
if (oldAvatarFileContent === newAvatarFileContent) {
res.avatar = null;
}
}
return res; return res;
} }