add file-chooser to the profile image selection

This commit is contained in:
2024-05-11 12:30:10 -06:00
parent f7b5dbf4ce
commit 17c901b1de
3 changed files with 108 additions and 51 deletions

View File

@@ -86,19 +86,25 @@
class="text-red-500 fa-fw ml-8 mt-8 w-12 h-12"
/>
</span>
<span v-else>
<fa
icon="camera"
class="bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-2 rounded-md"
@click="openPhotoDialog"
/>
</span>
<GiftedPhotoDialog ref="photoDialog" />
<div v-else class="text-center">
<div class>
<fa
icon="camera"
class="bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-2 rounded-md"
@click="openPhotoDialog(undefined, undefined)"
/>
</div>
<div>
<input type="file" @change="uploadPhotoFile" />
</div>
</div>
<PhotoDialog ref="photoDialog" />
</div>
<div class="mt-4">
<div class="flex justify-center">
... and those without your image see this (if you let them see your
activity):
<div class="mt-6">
<div class="flex justify-center text-center">
People without your image see this:
<br />
(if you've let them see your activity)
</div>
<div class="flex justify-center">
<EntityIcon
@@ -577,11 +583,11 @@
<div class="ml-4 mt-2">
Import
<input type="file" @change="uploadFile" class="ml-2" />
<input type="file" @change="uploadImportFile" class="ml-2" />
<div v-if="showContactImport()">
<button
class="block text-center text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-6"
@click="confirmSubmitFile()"
@click="confirmSubmitImportFile()"
>
Import Settings & Contacts
<br />
@@ -614,7 +620,7 @@ import { ref } from "vue";
import { Component, Vue } from "vue-facing-decorator";
import { useClipboard } from "@vueuse/core";
import GiftedPhotoDialog from "@/components/GiftedPhotoDialog.vue";
import PhotoDialog from "@/components/PhotoDialog.vue";
import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import {
@@ -645,10 +651,11 @@ interface IAccount {
derivationPath: string;
}
const inputFileNameRef = ref<Blob>();
const inputImportFileNameRef = ref<Blob>();
const inputPhotoFileNameRef = ref<Blob>();
@Component({
components: { EntityIcon, GiftedPhotoDialog, QuickNav, TopMessage },
components: { EntityIcon, PhotoDialog, QuickNav, TopMessage },
})
export default class AccountViewView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -1120,16 +1127,36 @@ export default class AccountViewView extends Vue {
console.error("Export Error:", error);
}
async uploadFile(event: Event) {
inputFileNameRef.value = event.target.files[0];
async uploadPhotoFile(event: Event) {
inputPhotoFileNameRef.value = event.target.files[0];
// https://developer.mozilla.org/en-US/docs/Web/API/File
// ... plus it has a `type` property from my testing
const file = inputPhotoFileNameRef.value;
if (file != null) {
const reader = new FileReader();
reader.onload = async (e) => {
const data = e.target?.result as ArrayBuffer;
if (data) {
const blob = new Blob([new Uint8Array(data)], {
type: file.type,
});
this.openPhotoDialog(blob, file.name as string);
}
};
reader.readAsArrayBuffer(file as Blob);
}
}
async uploadImportFile(event: Event) {
inputImportFileNameRef.value = event.target.files[0];
}
showContactImport() {
return !!inputFileNameRef.value;
return !!inputImportFileNameRef.value;
}
confirmSubmitFile() {
if (inputFileNameRef.value != null) {
confirmSubmitImportFile() {
if (inputImportFileNameRef.value != null) {
this.$notify(
{
group: "modal",
@@ -1138,7 +1165,7 @@ export default class AccountViewView extends Vue {
text:
"This will replace all settings and contacts, so we recommend you first do the backup step above." +
" Are you sure you want to import and replace all contacts and settings?",
onYes: this.submitFile,
onYes: this.submitImportFile,
},
-1,
);
@@ -1150,10 +1177,10 @@ export default class AccountViewView extends Vue {
*
* @throws Will notify the user if there is an export error.
*/
async submitFile() {
if (inputFileNameRef.value != null) {
async submitImportFile() {
if (inputImportFileNameRef.value != null) {
await db.delete();
await Dexie.import(inputFileNameRef.value as Blob, {
await Dexie.import(inputImportFileNameRef.value as Blob, {
progressCallback: this.progressCallback,
});
}
@@ -1366,8 +1393,8 @@ export default class AccountViewView extends Vue {
);
}
openPhotoDialog() {
(this.$refs.photoDialog as GiftedPhotoDialog).open(
openPhotoDialog(blob?: Blob, fileName?: string) {
(this.$refs.photoDialog as PhotoDialog).open(
async (imgUrl) => {
await db.open();
db.settings.update(MASTER_SETTINGS_KEY, {
@@ -1378,6 +1405,8 @@ export default class AccountViewView extends Vue {
},
true,
IMAGE_TYPE_PROFILE,
blob,
fileName,
);
}