feat: add post deletion confirm dialog (#818)
Co-authored-by: 三咲智子 <sxzz@sxzz.moe>
This commit is contained in:
parent
2ff46bb8cb
commit
d76e4bfaa5
28
components/modal/ModalConfirm.vue
Normal file
28
components/modal/ModalConfirm.vue
Normal file
|
@ -0,0 +1,28 @@
|
|||
<script setup lang="ts">
|
||||
import type { ConfirmDialogChoice, ConfirmDialogLabel } from '~/types'
|
||||
|
||||
defineProps<ConfirmDialogLabel>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(evt: 'choice', choice: ConfirmDialogChoice): void
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div flex="~ col" gap-6>
|
||||
<div font-bold text-lg text-center>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div v-if="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
<div flex justify-end gap-2>
|
||||
<button btn-text @click="emit('choice', 'cancel')">
|
||||
{{ cancel || $t('common.confirm_dialog.cancel') }}
|
||||
</button>
|
||||
<button btn-solid @click="emit('choice', 'confirm')">
|
||||
{{ confirm || $t('common.confirm_dialog.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,7 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
import type { Status } from 'masto'
|
||||
import type { ConfirmDialogChoice } from '~/types'
|
||||
import {
|
||||
isCommandPanelOpen,
|
||||
isConfirmDialogOpen,
|
||||
isEditHistoryDialogOpen,
|
||||
isMediaPreviewOpen,
|
||||
isPreviewHelpOpen,
|
||||
|
@ -36,6 +38,11 @@ const handlePublished = (status: Status) => {
|
|||
const handlePublishClose = () => {
|
||||
lastPublishDialogStatus.value = null
|
||||
}
|
||||
|
||||
const handleConfirmChoice = (choice: ConfirmDialogChoice) => {
|
||||
confirmDialogChoice.value = choice
|
||||
isConfirmDialogOpen.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -71,5 +78,8 @@ const handlePublishClose = () => {
|
|||
<ModalDialog v-model="isCommandPanelOpen" max-w-fit flex>
|
||||
<CommandPanel @close="closeCommandPanel()" />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isConfirmDialogOpen" py-4 px-8 max-w-125>
|
||||
<ModalConfirm v-if="confirmDialogLabel" v-bind="confirmDialogLabel" @choice="handleConfirmChoice" />
|
||||
</ModalDialog>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
@ -22,6 +22,7 @@ const {
|
|||
const clipboard = useClipboard()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { t } = useI18n()
|
||||
|
||||
const isAuthor = $computed(() => status.account.id === currentUser.value?.account.id)
|
||||
|
||||
|
@ -60,13 +61,12 @@ const shareLink = async (status: Status) => {
|
|||
}
|
||||
|
||||
const deleteStatus = async () => {
|
||||
// TODO confirm to delete
|
||||
if (process.dev) {
|
||||
// eslint-disable-next-line no-alert
|
||||
const result = confirm('[DEV] Are you sure you want to delete this post?')
|
||||
if (!result)
|
||||
return
|
||||
}
|
||||
if (await openConfirmDialog({
|
||||
title: t('menu.delete_confirm.title'),
|
||||
confirm: t('menu.delete_confirm.confirm'),
|
||||
cancel: t('menu.delete_confirm.cancel'),
|
||||
}) !== 'confirm')
|
||||
return
|
||||
|
||||
removeCachedStatus(status.id)
|
||||
await masto.statuses.remove(status.id)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import type { Attachment, Status, StatusEdit } from 'masto'
|
||||
import type { Draft } from '~/types'
|
||||
import type { ConfirmDialogChoice, ConfirmDialogLabel, Draft } from '~/types'
|
||||
import { STORAGE_KEY_FIRST_VISIT } from '~/constants'
|
||||
|
||||
export const confirmDialogChoice = ref<ConfirmDialogChoice>()
|
||||
export const confirmDialogLabel = ref<ConfirmDialogLabel>()
|
||||
|
||||
export const mediaPreviewList = ref<Attachment[]>([])
|
||||
export const mediaPreviewIndex = ref(0)
|
||||
|
||||
|
@ -18,6 +21,7 @@ export const isMediaPreviewOpen = ref(false)
|
|||
export const isEditHistoryDialogOpen = ref(false)
|
||||
export const isPreviewHelpOpen = ref(isFirstVisit.value)
|
||||
export const isCommandPanelOpen = ref(false)
|
||||
export const isConfirmDialogOpen = ref(false)
|
||||
|
||||
export const lastPublishDialogStatus = ref<Status | null>(null)
|
||||
|
||||
|
@ -25,6 +29,16 @@ export function openSigninDialog() {
|
|||
isSigninDialogOpen.value = true
|
||||
}
|
||||
|
||||
export async function openConfirmDialog(label: ConfirmDialogLabel | string): Promise<ConfirmDialogChoice> {
|
||||
confirmDialogLabel.value = typeof label === 'string' ? { title: label } : label
|
||||
confirmDialogChoice.value = undefined
|
||||
isConfirmDialogOpen.value = true
|
||||
|
||||
await until(isConfirmDialogOpen).toBe(false)
|
||||
|
||||
return confirmDialogChoice.value!
|
||||
}
|
||||
|
||||
export async function openPublishDialog(draftKey = 'dialog', draft?: Draft, overwrite = false): Promise<void> {
|
||||
dialogDraftKey.value = draftKey
|
||||
|
||||
|
|
|
@ -86,6 +86,11 @@
|
|||
"toggle_zen_mode": "Toggle zen mode"
|
||||
},
|
||||
"common": {
|
||||
"confirm_dialog": {
|
||||
"cancel": "No",
|
||||
"confirm": "Yes",
|
||||
"title": "Are you sure?"
|
||||
},
|
||||
"end_of_list": "End of the list",
|
||||
"error": "ERROR",
|
||||
"in": "in",
|
||||
|
@ -123,6 +128,11 @@
|
|||
"copy_link_to_post": "Copy link to this post",
|
||||
"delete": "Delete",
|
||||
"delete_and_redraft": "Delete & re-draft",
|
||||
"delete_confirm": {
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Delete",
|
||||
"title": "Are you sure you want to delete this post?"
|
||||
},
|
||||
"direct_message_account": "Direct message {0}",
|
||||
"edit": "Edit",
|
||||
"mention_account": "Mention {0}",
|
||||
|
|
|
@ -65,6 +65,14 @@ export interface Draft {
|
|||
}
|
||||
export type DraftMap = Record<string, Draft>
|
||||
|
||||
export interface ConfirmDialogLabel {
|
||||
title: string
|
||||
description?: string
|
||||
confirm?: string
|
||||
cancel?: string
|
||||
}
|
||||
export type ConfirmDialogChoice = 'confirm' | 'cancel'
|
||||
|
||||
export interface BuildInfo {
|
||||
version: string
|
||||
commit: string
|
||||
|
|
Loading…
Reference in a new issue