|
|
@ -86,19 +86,25 @@ |
|
|
|
class="text-red-500 fa-fw ml-8 mt-8 w-12 h-12" |
|
|
|
/> |
|
|
|
</span> |
|
|
|
<span v-else> |
|
|
|
<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" |
|
|
|
@click="openPhotoDialog(undefined, undefined)" |
|
|
|
/> |
|
|
|
</span> |
|
|
|
<GiftedPhotoDialog 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> |
|
|
|
<input type="file" @change="uploadPhotoFile" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<PhotoDialog ref="photoDialog" /> |
|
|
|
</div> |
|
|
|
<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, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|