Moment editor C-V upload attachment

This commit is contained in:
LittleSheep 2024-03-20 22:32:50 +08:00
parent 298e1fe617
commit 30e55a5c6e
3 changed files with 63 additions and 38 deletions

View File

@ -1,14 +1,15 @@
package server package server
import ( import (
"path/filepath"
"git.solsynth.dev/hydrogen/interactive/pkg/models" "git.solsynth.dev/hydrogen/interactive/pkg/models"
"git.solsynth.dev/hydrogen/interactive/pkg/services" "git.solsynth.dev/hydrogen/interactive/pkg/services"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/spf13/viper" "github.com/spf13/viper"
"path/filepath"
) )
func openAttachment(c *fiber.Ctx) error { func readAttachment(c *fiber.Ctx) error {
id := c.Params("fileId") id := c.Params("fileId")
basepath := viper.GetString("content") basepath := viper.GetString("content")

View File

@ -66,7 +66,7 @@ func NewServer() {
api.Get("/attachments/o/:fileId", cache.New(cache.Config{ api.Get("/attachments/o/:fileId", cache.New(cache.Config{
Expiration: 365 * 24 * time.Hour, Expiration: 365 * 24 * time.Hour,
CacheControl: true, CacheControl: true,
}), openAttachment) }), readAttachment)
api.Post("/attachments", authMiddleware, uploadAttachment) api.Post("/attachments", authMiddleware, uploadAttachment)
api.Get("/feed", listFeed) api.Get("/feed", listFeed)

View File

@ -13,6 +13,7 @@
label="What's happened?!" label="What's happened?!"
counter="1024" counter="1024"
v-model="data.content" v-model="data.content"
@paste="pasteMedia"
/> />
<div class="flex mt-[-18px]"> <div class="flex mt-[-18px]">
@ -31,6 +32,7 @@
<v-tooltip text="Media" location="start"> <v-tooltip text="Media" location="start">
<template #activator="{ props }"> <template #activator="{ props }">
<v-btn <v-btn
v-if="data.attachments.length <= 0"
v-bind="props" v-bind="props"
type="button" type="button"
variant="text" variant="text"
@ -38,6 +40,16 @@
size="small" size="small"
@click="dialogs.media = true" @click="dialogs.media = true"
/> />
<v-badge v-else size="small" color="red" :content="data.attachments.length">
<v-btn
v-bind="props"
type="button"
variant="text"
icon="mdi-camera"
size="small"
@click="dialogs.media = true"
/>
</v-badge>
</template> </template>
</v-tooltip> </v-tooltip>
<v-tooltip text="Publish area" location="start"> <v-tooltip text="Publish area" location="start">
@ -65,7 +77,7 @@
</v-card> </v-card>
<planned-publish v-model:show="dialogs.plan" v-model:value="data.published_at" /> <planned-publish v-model:show="dialogs.plan" v-model:value="data.published_at" />
<media v-model:show="dialogs.media" v-model:uploading="uploading" v-model:value="data.attachments" /> <media ref="media" v-model:show="dialogs.media" v-model:uploading="uploading" v-model:value="data.attachments" />
<publish-area v-model:show="dialogs.area" v-model:value="data.realm_id" /> <publish-area v-model:show="dialogs.area" v-model:value="data.realm_id" />
<v-snackbar v-model="success" :timeout="3000">Your post has been published.</v-snackbar> <v-snackbar v-model="success" :timeout="3000">Your post has been published.</v-snackbar>
@ -79,70 +91,82 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
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 { reactive, ref, watch } from "vue"; import { reactive, ref, watch } from "vue"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
import PlannedPublish from "@/components/publish/parts/PlannedPublish.vue"; import PlannedPublish from "@/components/publish/parts/PlannedPublish.vue"
import Media from "@/components/publish/parts/Media.vue"; import Media from "@/components/publish/parts/Media.vue"
import PublishArea from "@/components/publish/parts/PublishArea.vue"; import PublishArea from "@/components/publish/parts/PublishArea.vue"
const editor = useEditor(); const editor = useEditor()
const dialogs = reactive({ const dialogs = reactive({
plan: false, plan: false,
media: false, media: false,
area: false area: false
}); })
const data = ref<any>({ const data = ref<any>({
content: "", content: "",
realm_id: null, realm_id: null,
published_at: null, published_at: null,
attachments: [] attachments: []
}); })
const error = ref<string | null>(null); const error = ref<string | null>(null)
const success = ref(false); const success = ref(false)
const loading = ref(false); const loading = ref(false)
const uploading = ref(false); const uploading = ref(false)
const router = useRouter(); const router = useRouter()
async function postMoment(evt: SubmitEvent) { async function postMoment(evt: SubmitEvent) {
const form = evt.target as HTMLFormElement; const form = evt.target as HTMLFormElement
const payload = data.value; const payload = data.value
if (!payload.content) return; if (!payload.content) return
if (!payload.published_at) payload.published_at = new Date().toISOString(); if (!payload.published_at) payload.published_at = new Date().toISOString()
if (!payload.realm_id) payload.realm_id = undefined; if (!payload.realm_id) payload.realm_id = undefined
const url = editor.related.edit_to ? `/api/p/moments/${editor.related.edit_to?.id}` : "/api/p/moments"; const url = editor.related.edit_to ? `/api/p/moments/${editor.related.edit_to?.id}` : "/api/p/moments"
const method = editor.related.edit_to ? "PUT" : "POST"; const method = editor.related.edit_to ? "PUT" : "POST"
loading.value = true; loading.value = true
const res = await request(url, { const res = await request(url, {
method: method, method: method,
headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` }, headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
body: JSON.stringify(payload) body: JSON.stringify(payload)
}); })
if (res.status === 200) { if (res.status === 200) {
form.reset(); form.reset()
const data = await res.json(); const data = await res.json()
success.value = true; success.value = true
editor.show.moment = false; editor.show.moment = false
router.push({ name: "posts.details.moments", params: { alias: data.alias } }); router.push({ name: "posts.details.moments", params: { alias: data.alias } })
} else { } else {
error.value = await res.text(); error.value = await res.text()
}
loading.value = false
}
const media = ref<any>(null)
function pasteMedia(evt: ClipboardEvent) {
const files = evt.clipboardData?.files
if (files) {
Array.from(files).forEach((item) => {
media.value.upload(item)
})
evt.preventDefault()
} }
loading.value = false;
} }
watch(editor.related, (val) => { watch(editor.related, (val) => {
if (val.edit_to && val.edit_to.model_type === "moment") { if (val.edit_to && val.edit_to.model_type === "moment") {
data.value = val.edit_to; data.value = val.edit_to
} }
}); })
</script> </script>
<style> <style>