External attachments

This commit is contained in:
LittleSheep 2024-02-05 20:02:37 +08:00
parent 22ad495308
commit 8cb6b699e5
4 changed files with 87 additions and 33 deletions

View File

@ -9,14 +9,15 @@ import (
type Attachment struct {
BaseModel
FileID string `json:"file_id"`
Filesize int64 `json:"filesize"`
Filename string `json:"filename"`
Mimetype string `json:"mimetype"`
Post *Post `json:"post"`
Author Account `json:"author"`
PostID *uint `json:"post_id"`
AuthorID uint `json:"author_id"`
FileID string `json:"file_id"`
Filesize int64 `json:"filesize"`
Filename string `json:"filename"`
Mimetype string `json:"mimetype"`
ExternalUrl string `json:"external_url"`
Post *Post `json:"post"`
Author Account `json:"author"`
PostID *uint `json:"post_id"`
AuthorID uint `json:"author_id"`
}
func (v Attachment) GetStoragePath() string {

View File

@ -14,7 +14,7 @@ export default function PostAttachments(props: { attachments: any[] }) {
}
function getUrl(item: any): string {
return `/api/attachments/o/${item.file_id}`;
return item.external_url ?? `/api/attachments/o/${item.file_id}`;
}
createEffect(() => {
@ -36,8 +36,8 @@ export default function PostAttachments(props: { attachments: any[] }) {
<i class="fa-solid fa-circle-question text-3xl"></i>
<p class="mt-3">{item().filename}</p>
<div class="flex gap-3 w-full">
<p class="text-sm">{item().filesize} Bytes</p>
<div class="flex gap-2 w-full">
<p class="text-sm">{item().filesize <= 0 ? "Unknown" : item().filesize} Bytes</p>
<p class="text-sm">{item().mimetype}</p>
</div>

View File

@ -1,4 +1,4 @@
import { createEffect, createSignal, For, Show } from "solid-js";
import { createEffect, createSignal, For, Match, Show, Switch } from "solid-js";
import { getAtk, useUserinfo } from "../stores/userinfo.tsx";
import styles from "./PostPublish.module.css";
@ -22,6 +22,8 @@ export default function PostPublish(props: {
const [categories, setCategories] = createSignal<{ alias: string, name: string }[]>([]);
const [tags, setTags] = createSignal<{ alias: string, name: string }[]>([]);
const [attachmentMode, setAttachmentMode] = createSignal(0);
createEffect(() => {
setAttachments(props.editing?.attachments ?? []);
setCategories(props.editing?.categories ?? []);
@ -101,7 +103,7 @@ export default function PostPublish(props: {
setSubmitting(false);
}
async function uploadAttachments(evt: SubmitEvent) {
async function uploadAttachment(evt: SubmitEvent) {
evt.preventDefault();
const form = evt.target as HTMLFormElement;
@ -125,6 +127,19 @@ export default function PostPublish(props: {
setUploading(false);
}
function addAttachment(evt: SubmitEvent) {
evt.preventDefault();
const form = evt.target as HTMLFormElement;
const data = Object.fromEntries(new FormData(form));
setAttachments(attachments().concat([{
...data,
author_id: userinfo?.profiles?.id,
}]));
form.reset();
}
function addCategory(evt: SubmitEvent) {
evt.preventDefault();
@ -138,7 +153,7 @@ export default function PostPublish(props: {
}
function removeCategory(target: any) {
setCategories(categories().filter(item => item.alias !== target.alias))
setCategories(categories().filter(item => item.alias !== target.alias));
}
function addTag(evt: SubmitEvent) {
@ -154,7 +169,7 @@ export default function PostPublish(props: {
}
function removeTag(target: any) {
setTags(tags().filter(item => item.alias !== target.alias))
setTags(tags().filter(item => item.alias !== target.alias));
}
function resetForm() {
@ -270,23 +285,60 @@ export default function PostPublish(props: {
<dialog id="attachments" class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg mx-1">Attachments</h3>
<form class="w-full mt-3" onSubmit={uploadAttachments}>
<label class="form-control">
<div class="label">
<span class="label-text">Pick a file</span>
</div>
<div class="join">
<input required type="file" name="attachment"
class="join-item file-input file-input-bordered w-full" />
<button type="submit" class="join-item btn btn-primary" disabled={uploading()}>
<i class="fa-solid fa-upload"></i>
</button>
</div>
<div class="label">
<span class="label-text-alt">Click upload to add this file into list</span>
</div>
</label>
</form>
<div role="tablist" class="tabs tabs-boxed mt-3">
<input type="radio" name="attachment" role="tab" class="tab" aria-label="File picker"
checked={attachmentMode() === 0} onClick={() => setAttachmentMode(0)} />
<input type="radio" name="attachment" role="tab" class="tab" aria-label="External link"
checked={attachmentMode() === 1} onClick={() => setAttachmentMode(1)} />
</div>
<Switch>
<Match when={attachmentMode() === 0}>
<form class="w-full mt-2" onSubmit={uploadAttachment}>
<label class="form-control">
<div class="label">
<span class="label-text">Pick a file</span>
</div>
<div class="join">
<input required type="file" name="attachment"
class="join-item file-input file-input-bordered w-full" />
<button type="submit" class="join-item btn btn-primary" disabled={uploading()}>
<i class="fa-solid fa-upload"></i>
</button>
</div>
<div class="label">
<span class="label-text-alt">Click upload to add this file into list</span>
</div>
</label>
</form>
</Match>
<Match when={attachmentMode() === 1}>
<form class="w-full mt-2" onSubmit={addAttachment}>
<label class="form-control">
<div class="label">
<span class="label-text">Attach an external file</span>
</div>
<div class="join">
<input required type="text" name="mimetype" class="join-item input input-bordered w-full"
placeholder="Mimetype" />
<input required type="text" name="filename" class="join-item input input-bordered w-full"
placeholder="Name" />
</div>
<div class="join">
<input required type="text" name="external_url" class="join-item input input-bordered w-full"
placeholder="External URL" />
<button type="submit" class="join-item btn btn-primary">
<i class="fa-solid fa-plus"></i>
</button>
</div>
<div class="label">
<span class="label-text-alt">Click add button to add it into list</span>
</div>
</label>
</form>
</Match>
</Switch>
<Show when={attachments().length > 0}>
<h3 class="font-bold mt-3 mx-1">Attachment list</h3>

View File

@ -11,7 +11,8 @@ interface MenuItem {
export default function Navbar() {
const nav: MenuItem[] = [
{ label: "Feed", href: "/" }
{ label: "Feed", href: "/" },
{ label: "Realms", href: "/realms" }
];
const wellKnown = useWellKnown();