native dialog on android & ios

This commit is contained in:
2023-05-31 00:29:10 +02:00
parent ec802259a8
commit 9cd6382bfc
4 changed files with 82 additions and 29 deletions

15
package-lock.json generated
View File

@@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"@capacitor/android": "^5.0.4", "@capacitor/android": "^5.0.4",
"@capacitor/core": "^5.0.4", "@capacitor/core": "^5.0.4",
"@capacitor/dialog": "^5.0.2",
"@capacitor/ios": "^5.0.4", "@capacitor/ios": "^5.0.4",
"@ckeditor/ckeditor5-autoformat": "^37.1.0", "@ckeditor/ckeditor5-autoformat": "^37.1.0",
"@ckeditor/ckeditor5-basic-styles": "^37.1.0", "@ckeditor/ckeditor5-basic-styles": "^37.1.0",
@@ -266,6 +267,14 @@
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@capacitor/dialog": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@capacitor/dialog/-/dialog-5.0.2.tgz",
"integrity": "sha512-9SCknNv2Z9Q3MazjA2a8uZbbmbsGViO0k6OcKgirccXbJoz0uj2x8XiNqOaqLZKeZn0zSD3Lu7J4eJYmLFH+AQ==",
"peerDependencies": {
"@capacitor/core": "^5.0.0"
}
},
"node_modules/@capacitor/ios": { "node_modules/@capacitor/ios": {
"version": "5.0.4", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-5.0.4.tgz", "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-5.0.4.tgz",
@@ -13342,6 +13351,12 @@
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"@capacitor/dialog": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@capacitor/dialog/-/dialog-5.0.2.tgz",
"integrity": "sha512-9SCknNv2Z9Q3MazjA2a8uZbbmbsGViO0k6OcKgirccXbJoz0uj2x8XiNqOaqLZKeZn0zSD3Lu7J4eJYmLFH+AQ==",
"requires": {}
},
"@capacitor/ios": { "@capacitor/ios": {
"version": "5.0.4", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-5.0.4.tgz", "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-5.0.4.tgz",

View File

@@ -17,6 +17,7 @@
"dependencies": { "dependencies": {
"@capacitor/android": "^5.0.4", "@capacitor/android": "^5.0.4",
"@capacitor/core": "^5.0.4", "@capacitor/core": "^5.0.4",
"@capacitor/dialog": "^5.0.2",
"@capacitor/ios": "^5.0.4", "@capacitor/ios": "^5.0.4",
"@ckeditor/ckeditor5-autoformat": "^37.1.0", "@ckeditor/ckeditor5-autoformat": "^37.1.0",
"@ckeditor/ckeditor5-basic-styles": "^37.1.0", "@ckeditor/ckeditor5-basic-styles": "^37.1.0",

View File

@@ -1,11 +1,53 @@
<script setup lang="ts"> <script setup lang="ts">
import { Capacitor } from '@capacitor/core'
import { Dialog } from '@capacitor/dialog'
import type { ConfirmOptions } from '@capacitor/dialog'
const props = defineProps<{ const props = defineProps<{
note: Note note: Note
}>() }>()
type ActionKey = 'delete' | 'setRoot'
interface ModalOptions {
key: ActionKey
icon: string
confirmOptions: ConfirmOptions
}
const confirmModals: ModalOptions[] = [
{
key: 'delete',
icon: 'fas fa-fw fa-trash',
confirmOptions: {
title: 'Delete note',
message: 'Are you sure you want to delete this note?',
okButtonTitle: 'Delete note'
}
},
{
key: 'setRoot',
icon: 'fas fa-fw fa-sitemap',
confirmOptions: {
title: 'Set root note',
message: 'Are you sure you want to set this note as root note?',
okButtonTitle: 'Set note as root note'
}
}
]
const emit = defineEmits<{ const emit = defineEmits<{
delete: [close: () => void] execute: [actionType: ActionKey, close?: () => void]
setRoot: [close: () => void]
}>() }>()
const openModal = async (open: () => void, modal: ModalOptions) => {
if (['android', 'ios'].includes(Capacitor.getPlatform())) {
const { value: confirmed } = await Dialog.confirm(modal.confirmOptions)
if (confirmed) emit('execute', modal.key)
} else {
open()
}
}
</script> </script>
<template> <template>
<div class="mb-2 flex items-center space-x-2"> <div class="mb-2 flex items-center space-x-2">
@@ -13,27 +55,21 @@ const emit = defineEmits<{
<slot name="title"></slot> <slot name="title"></slot>
</h1> </h1>
<UIButtonGroup class="flex items-center" v-if="!props.note.isRoot"> <UIButtonGroup class="flex items-center" v-if="!props.note.isRoot">
<UIModal> <UIModal v-for="confirmModal in confirmModals" :key="confirmModal.key">
<template #activator="{ open }"> <template #activator="{ open }">
<UIButton size="sm" @click="open"><i class="fas fa-fw fa-trash" /></UIButton> <UIButton size="sm" @click="openModal(open, confirmModal)">
<i :class="confirmModal.icon" />
</UIButton>
</template> </template>
<template #title><i class="fas fa-fw fa-trash mr-2" />Delete note</template> <template #title>
<template #default>Are you sure you want to delete this note?</template> <i class="mr-2" :class="confirmModal.icon" />
<template #actions="{ close }"> {{ confirmModal.confirmOptions.title }}
<UIButton size="sm" color="primary" @click="emit('delete', close)">Delete notes</UIButton>
<UIButton size="sm" @click="close">Cancel</UIButton>
</template> </template>
</UIModal> <template #default>{{ confirmModal.confirmOptions.message }}</template>
<UIModal>
<template #activator="{ open }">
<UIButton size="sm" @click="open"><i class="fas fa-fw fa-sitemap" /></UIButton>
</template>
<template #title><i class="fas fa-fw fa-sitemap mr-2" />Set root note</template>
<template #default>Are you sure you want to set this note as root note?</template>
<template #actions="{ close }"> <template #actions="{ close }">
<UIButton size="sm" @click="close">Cancel</UIButton> <UIButton size="sm" @click="close">Cancel</UIButton>
<UIButton size="sm" color="primary" @click="emit('setRoot', close)"> <UIButton size="sm" color="primary" @click="emit('execute', confirmModal.key, close)">
Set current note as root {{ confirmModal.confirmOptions.okButtonTitle }}
</UIButton> </UIButton>
</template> </template>
</UIModal> </UIModal>

View File

@@ -30,26 +30,27 @@ const updateNoteContent = (content: string) => {
const references = computed<Note[]>(() => getNoteReferences(props.note)) const references = computed<Note[]>(() => getNoteReferences(props.note))
const del = async (closeModal: () => Promise<Boolean>) => { const handleAction = async (action: string, closeModal: () => Promise<Boolean>) => {
await closeModal() if (action === 'delete') {
setActiveNote(rootNote.value?.id) if (closeModal) await closeModal()
deleteNote(props.note.id) setActiveNote(rootNote.value?.id)
} deleteNote(props.note.id)
}
const setRoot = async (closeModal: () => Promise<Boolean>) => { if (action === 'setRoot') {
setRootNote(props.note.id) setRootNote(props.note.id)
closeModal() if (closeModal) closeModal()
}
} }
</script> </script>
<template> <template>
<div class="flex flex-grow flex-col"> <div class="flex flex-grow flex-col">
<NoteToolbar :note="props.note" @delete="del" @set-root="setRoot"> <NoteToolbar :note="props.note" @execute="handleAction">
<template #title> <template #title>
<i <i
class="fas fa-fw fa-home mr-2 text-base text-secondary opacity-40" class="fas fa-fw fa-home mr-2 text-base text-secondary opacity-40"
v-if="props.note.isRoot" v-if="props.note.isRoot"
></i> ></i>
<input type="text" class="bg-transparent pb-1 outline-none w-full" v-model="noteTitle" /> <input type="text" class="w-full bg-transparent pb-1 outline-none" v-model="noteTitle" />
</template> </template>
</NoteToolbar> </NoteToolbar>
<NoteEditor <NoteEditor