Improve avatar selection on edit identity
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
4a11d4adcc
commit
0be3e0c9fa
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue