Deletion

This commit is contained in:
LittleSheep 2024-03-11 23:03:07 +08:00
parent 7b2a6c3709
commit f5ebc1748a
9 changed files with 115 additions and 21 deletions

View File

@ -3,7 +3,7 @@
<v-progress-circular indeterminate /> <v-progress-circular indeterminate />
</div> </div>
<div v-else class="flex flex-col gap-2 mt-3"> <div v-else class="flex flex-col gap-5 mt-3">
<div v-for="(item, idx) in props.comments" class="text-sm"> <div v-for="(item, idx) in props.comments" class="text-sm">
<post-item :item="item" @update:item="(val) => updateItem(idx, val)" /> <post-item :item="item" @update:item="(val) => updateItem(idx, val)" />
</div> </div>

View File

@ -47,7 +47,7 @@
<v-list density="compact" lines="one"> <v-list density="compact" lines="one">
<v-list-item disabled append-icon="mdi-flag" title="Report" /> <v-list-item disabled append-icon="mdi-flag" title="Report" />
<v-list-item v-if="isOwned" append-icon="mdi-pencil" title="Edit" @click="editPost" /> <v-list-item v-if="isOwned" append-icon="mdi-pencil" title="Edit" @click="editPost" />
<v-list-item v-if="isOwned" append-icon="mdi-delete" title="Delete" /> <v-list-item v-if="isOwned" append-icon="mdi-delete" title="Delete" @click="deletePost" />
</v-list> </v-list>
</v-menu> </v-menu>
</div> </div>
@ -85,6 +85,15 @@ function editPost() {
// @ts-ignore // @ts-ignore
editor.show[props.item.model_type] = true editor.show[props.item.model_type] = true
} }
if (props.item.model_type === "comment") {
editor.related.comment_to = props.item
}
}
function deletePost() {
editor.related.delete_to = JSON.parse(JSON.stringify(props.item))
editor.related.delete_to.model_type = props.item.model_type + "s"
editor.show.delete = true
} }
function updateReactions(symbol: string, num: number) { function updateReactions(symbol: string, num: number) {

View File

@ -21,7 +21,7 @@
<v-card-text> <v-card-text>
<v-container class="article-container"> <v-container class="article-container">
<v-alert v-if="editor.related.edit_to" class="mb-3" type="info" variant="tonal"> <v-alert v-if="editor.related.edit_to" class="mb-5" type="info" variant="tonal">
You are editing a post with alias <b class="font-mono">{{ editor.related.edit_to?.alias }}</b> You are editing a post with alias <b class="font-mono">{{ editor.related.edit_to?.alias }}</b>
</v-alert> </v-alert>

View File

@ -2,7 +2,11 @@
<v-card title="Leave your comment" :loading="loading"> <v-card title="Leave your comment" :loading="loading">
<v-form @submit.prevent="postComment"> <v-form @submit.prevent="postComment">
<v-card-text> <v-card-text>
<v-textarea required hide-details name="content" variant="outlined" label="What do you want to say?" /> <v-alert v-if="editor.related.edit_to" class="mb-5" type="info" variant="tonal">
You are editing a comment with alias <b class="font-mono">{{ editor.related.edit_to?.alias }}</b>
</v-alert>
<v-textarea required hide-details variant="outlined" label="What do you want to say?" v-model="data.content" />
<p class="px-2 mt-1 text-body-2 opacity-80">Your comment will leave below {{ postIdentifier }}</p> <p class="px-2 mt-1 text-body-2 opacity-80">Your comment will leave below {{ postIdentifier }}</p>
</v-card-text> </v-card-text>
@ -26,7 +30,7 @@
import { request } from "@/scripts/request" import { request } from "@/scripts/request"
import { useEditor } from "@/stores/editor" import { useEditor } from "@/stores/editor"
import { getAtk } from "@/stores/userinfo" import { getAtk } from "@/stores/userinfo"
import { computed, ref } from "vue" import { computed, ref, watch } from "vue"
const editor = useEditor() const editor = useEditor()
@ -43,16 +47,26 @@ const error = ref<string | null>(null)
const success = ref(false) const success = ref(false)
const loading = ref(false) const loading = ref(false)
const data = ref<any>({
content: ""
})
async function postComment(evt: SubmitEvent) { async function postComment(evt: SubmitEvent) {
const form = evt.target as HTMLFormElement const form = evt.target as HTMLFormElement
const data = new FormData(form) const payload = data.value
if (!data.has("content")) return
if (!payload.content) return
const url = editor.related.edit_to
? `/api/p/comments/${editor.related.edit_to?.id}`
: `/api/p/${target.value?.model_type}/${target.value?.alias}/comments`
const method = editor.related.edit_to ? "PUT" : "POST"
loading.value = true loading.value = true
const res = await request(`/api/p/${target.value?.model_type}/${target.value?.alias}/comments`, { const res = await request(url, {
method: "POST", method: method,
headers: { Authorization: `Bearer ${getAtk()}` }, headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
body: data body: JSON.stringify(payload)
}) })
if (res.status === 200) { if (res.status === 200) {
form.reset() form.reset()
@ -64,4 +78,10 @@ async function postComment(evt: SubmitEvent) {
loading.value = false loading.value = false
editor.done = true editor.done = true
} }
watch(editor.related, (val) => {
if (val.edit_to && val.edit_to.model_type === "comment") {
data.value = val.edit_to
}
})
</script> </script>

View File

@ -2,7 +2,7 @@
<v-card title="Record a moment" :loading="loading"> <v-card title="Record a moment" :loading="loading">
<v-form @submit.prevent="postMoment"> <v-form @submit.prevent="postMoment">
<v-card-text> <v-card-text>
<v-alert v-if="editor.related.edit_to" class="mb-3" type="info" variant="tonal"> <v-alert v-if="editor.related.edit_to" class="mb-5" type="info" variant="tonal">
You are editing a post with alias <b class="font-mono">{{ editor.related.edit_to?.alias }}</b> You are editing a post with alias <b class="font-mono">{{ editor.related.edit_to?.alias }}</b>
</v-alert> </v-alert>
@ -117,7 +117,7 @@ async function postMoment(evt: SubmitEvent) {
} }
watch(editor.related, (val) => { watch(editor.related, (val) => {
if (val.edit_to) { if (val.edit_to && val.edit_to.model_type === "moment") {
data.value = val.edit_to data.value = val.edit_to
} }
}) })

View File

@ -8,13 +8,18 @@
<v-dialog v-model="editor.show.article" transition="dialog-bottom-transition" fullscreen eager> <v-dialog v-model="editor.show.article" transition="dialog-bottom-transition" fullscreen eager>
<article-editor /> <article-editor />
</v-dialog> </v-dialog>
<v-dialog v-model="editor.show.delete" class="max-w-[540px]" eager>
<post-deletion />
</v-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useEditor } from "@/stores/editor" import { useEditor } from "@/stores/editor"
import MomentEditor from "@/components/publish/MomentEditor.vue" import MomentEditor from "@/components/publish/MomentEditor.vue"
import CommentEditor from "@/components/publish/CommentEditor.vue"; import CommentEditor from "@/components/publish/CommentEditor.vue"
import ArticleEditor from "@/components/publish/ArticleEditor.vue"; import ArticleEditor from "@/components/publish/ArticleEditor.vue"
import PostDeletion from "@/components/publish/PostDeletion.vue"
const editor = useEditor() const editor = useEditor()
</script> </script>

View File

@ -0,0 +1,51 @@
<template>
<v-card title="Delete a post" :loading="loading">
<template #text>
You are deleting a post with alias
<b class="font-mono">{{ editor.related.delete_to?.alias }}</b>
Are you confirm?
</template>
<template #actions>
<div class="w-full flex justify-end">
<v-btn color="grey-darken-3" @click="editor.show.delete = false">Not really</v-btn>
<v-btn color="error" :disabled="loading" @click="deletePost">Yes</v-btn>
</div>
</template>
</v-card>
<v-snackbar v-model="success" :timeout="3000">The post has been deleted.</v-snackbar>
<!-- @vue-ignore -->
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
</template>
<script setup lang="ts">
import { useEditor } from "@/stores/editor"
import { getAtk } from "@/stores/userinfo"
import { ref } from "vue"
const editor = useEditor()
const error = ref<string | null>(null)
const success = ref(false)
const loading = ref(false)
async function deletePost() {
const target = editor.related.delete_to
const url = `/api/p/${target.model_type}/${target.id}`
loading.value = true
const res = await fetch(url, {
method: "DELETE",
headers: { Authorization: `Bearer ${getAtk()}` }
})
if (res.status !== 200) {
error.value = await res.text()
} else {
success.value = true
editor.show.delete = false
editor.related.delete_to = null
}
loading.value = false
}
</script>

View File

@ -1,5 +1,6 @@
import { defineStore } from "pinia" import { defineStore } from "pinia"
import { reactive, ref } from "vue" import { reactive, ref } from "vue"
import { getAtk } from "@/stores/userinfo"
export const useEditor = defineStore("editor", () => { export const useEditor = defineStore("editor", () => {
const done = ref(false) const done = ref(false)
@ -7,14 +8,22 @@ export const useEditor = defineStore("editor", () => {
const show = reactive({ const show = reactive({
moment: false, moment: false,
article: false, article: false,
comment: false comment: false,
delete: false
}) })
const related = reactive<{ edit_to: any; comment_to: any; reply_to: any; repost_to: any }>({ const related = reactive<{
edit_to: any
comment_to: any
reply_to: any
repost_to: any
delete_to: any
}>({
edit_to: null, edit_to: null,
comment_to: null, comment_to: null,
reply_to: null, reply_to: null,
repost_to: null repost_to: null,
delete_to: null
}) })
return { show, related, done } return { show, related, done }

View File

@ -1,6 +1,6 @@
<template> <template>
<v-container class="flex max-md:flex-col gap-3 overflow-auto max-h-[calc(100vh-64px)] no-scrollbar"> <v-container class="flex max-md:flex-col gap-3 overflow-auto max-h-[calc(100vh-64px)] no-scrollbar">
<div class="timeline flex-grow-1"> <div class="content flex-grow-1">
<v-card :loading="loading"> <v-card :loading="loading">
<article> <article>
<v-card-text> <v-card-text>
@ -26,7 +26,7 @@
</v-card> </v-card>
</div> </div>
<div class="aside sticky top-0 w-full h-fit md:max-w-[360px] md:min-w-[280px]"> <div class="aside sticky top-0 w-full h-fit w-full md:max-w-[380px] md:min-w-[360px]">
<v-card title="Comments"> <v-card title="Comments">
<div class="px-[1rem] pb-[0.825rem] mt-[-12px]"> <div class="px-[1rem] pb-[0.825rem] mt-[-12px]">
<comment-list <comment-list