add profile picture

Is hidden because the API not accept the image in base64
This commit is contained in:
Gabriel Pastori 2023-12-08 16:32:49 -03:00
parent 1465e73f8e
commit 7579b85cbf
5 changed files with 214 additions and 11 deletions

View File

@ -37,6 +37,7 @@ import HasWhatsapp from "./message/HasWhatsapp.vue";
import ConnectionAlert from "./profile/ConnectionAlert.vue";
import BasicInfo from "./profile/BasicInfo.vue";
import Privacy from "./profile/Privacy.vue";
import ProfilePhoto from "./profile/ProfilePhoto.vue";
export default {
components: {
Options,
@ -53,6 +54,7 @@ export default {
ConnectionAlert,
BasicInfo,
Privacy,
ProfilePhoto,
},
data: () => ({
tab: "settings",
@ -86,7 +88,12 @@ export default {
id: "profile",
icon: "mdi-account",
title: "Perfil",
components: ["ConnectionAlert", "BasicInfo", "Privacy"],
components: [
"ConnectionAlert",
"BasicInfo",
// "ProfilePhoto",
"Privacy",
],
},
],
}),

View File

@ -7,20 +7,15 @@
<v-avatar size="100" rounded="xl">
<v-icon
v-if="
instance.instance.status != 'open' &&
(instance.instance.status != 'open' ||
instance.instance.profilePictureUrl == null) &&
statusMapper[instance.instance.status].icon
"
size="70"
>
{{ statusMapper[instance.instance.status].icon }}
</v-icon>
<v-img
v-else
:src="
instance.instance.profilePictureUrl ||
'https://cdn.vuetifyjs.com/images/lists/1.jpg'
"
/>
<v-img v-else :src="instance.instance.profilePictureUrl" />
</v-avatar>
<div class="d-flex flex-column">
<span class="text-overline" style="line-height: 1em">

View File

@ -101,7 +101,6 @@
</v-btn>
</v-card-actions>
</v-card>
<chatwoot-config :instance="instance" ref="chatwootConfig" />
</template>
<script>

View File

@ -0,0 +1,175 @@
<template>
<v-card variant="outlined" :loading="loading">
<v-card-title
class="d-flex align-center"
@click="toggleExpanded"
style="cursor: pointer"
v-ripple
>
<v-icon start>mdi-account-box</v-icon>
Foto de Perfil
<v-spacer></v-spacer>
<v-btn
size="small"
icon
:disabled="loading"
variant="tonal"
@click.stop="toggleExpanded"
:style="{ transform: expanded ? 'rotate(180deg)' : '' }"
>
<v-icon>mdi-chevron-down</v-icon>
</v-btn>
</v-card-title>
<v-card-text v-if="expanded">
<v-alert v-if="error" type="error" class="mb-3">
{{ error }}
</v-alert>
<div class="d-flex gap-x-4">
{{ instance.instance.profilePictureUrl }}
<v-avatar size="150">
<v-img
v-if="instance.instance.profilePictureUrl"
:src="instance.instance.profilePictureUrl"
:alt="instance.instance.profileName"
/>
<div v-else class="d-flex flex-column align-center">
<v-icon size="70"> mdi-account-question </v-icon>
Sem foto de perfil
</div>
</v-avatar>
<v-card
variant="outlined"
class="h-full d-flex flex-column justify-center align-center rounded-pill"
width="150"
@click="selectPhoto"
>
<v-icon size="50">mdi-upload</v-icon>
Selecionar foto
</v-card>
<v-card
v-if="instance.instance.profilePictureUrl"
variant="outlined"
class="h-full d-flex justify-center align-center rounded-pill"
width="150"
@click="removePicture"
:disabled="loading"
>
<v-progress-circular
indeterminate
v-if="loading == 'removing'"
size="50"
/>
<v-icon size="50" v-else>mdi-delete</v-icon>
Remover foto
</v-card>
</div>
<input
type="file"
accept="image/*"
ref="fileInput"
style="display: none"
@change="upload"
/>
</v-card-text>
</v-card>
</template>
<script>
import instanceController from "@/services/instanceController";
import { useAppStore } from "@/store/app";
export default {
name: "ProfilePhoto",
props: {
instance: {
type: Object,
required: true,
},
},
data: () => ({
AppStore: useAppStore(),
expanded: false,
loading: false,
error: false,
valid: false,
data: {
name: "",
status: "",
},
defaultData: {
name: "",
status: "",
},
}),
methods: {
toggleExpanded() {
if (this.loading) return;
this.expanded = !this.expanded;
},
async removePicture() {
try {
this.loading = "removing";
this.error = false;
if (!this.isOpen) return;
await instanceController.profile.removePicture(
this.instance.instance.instanceName
);
await this.AppStore.reconnect();
} catch (e) {
this.error = e.message?.message || e.message || e;
} finally {
this.loading = false;
}
},
async upload(event) {
try {
this.loading = "uploading";
this.error = false;
if (!this.isOpen) return;
const file = event.target.files[0];
debugger;
const base64 = await this.fileToBase64(file);
await instanceController.profile.updatePicture(
this.instance.instance.instanceName,
base64
);
await this.AppStore.reconnect();
} catch (e) {
this.error = e.message?.message || e.message || e;
} finally {
this.loading = false;
}
},
fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
});
},
selectPhoto() {
if (this.loading) return;
this.$refs.fileInput.click();
},
},
computed: {
isOpen() {
return this.instance.instance.status === "open";
},
},
};
</script>
<style></style>

View File

@ -54,9 +54,36 @@ const updatePrivacy = async (instanceName, privacySettings) => {
}
const removePicture = async (instanceName) => {
return await http
.delete("/chat/removeProfilePicture/:instance", {
params: {
instance: instanceName
}
})
.then((r) => r.data)
.catch((error) => {
throw error.response?.data || error.response || error;
});
}
const updatePicture = async (instanceName, picture) => {
return await http
.put("/chat/updateProfilePicture/:instance", { picture }, {
params: {
instance: instanceName
}
})
.then((r) => r.data)
.catch((error) => {
throw error.response?.data || error.response || error;
});
}
export default {
updateName: updateName,
updateStatus: updateStatus,
getPrivacy: getPrivacy,
updatePrivacy: updatePrivacy
updatePrivacy: updatePrivacy,
removePicture: removePicture,
updatePicture: updatePicture,
}