✨ External attachments
This commit is contained in:
parent
22ad495308
commit
8cb6b699e5
@ -9,14 +9,15 @@ import (
|
|||||||
type Attachment struct {
|
type Attachment struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
FileID string `json:"file_id"`
|
FileID string `json:"file_id"`
|
||||||
Filesize int64 `json:"filesize"`
|
Filesize int64 `json:"filesize"`
|
||||||
Filename string `json:"filename"`
|
Filename string `json:"filename"`
|
||||||
Mimetype string `json:"mimetype"`
|
Mimetype string `json:"mimetype"`
|
||||||
Post *Post `json:"post"`
|
ExternalUrl string `json:"external_url"`
|
||||||
Author Account `json:"author"`
|
Post *Post `json:"post"`
|
||||||
PostID *uint `json:"post_id"`
|
Author Account `json:"author"`
|
||||||
AuthorID uint `json:"author_id"`
|
PostID *uint `json:"post_id"`
|
||||||
|
AuthorID uint `json:"author_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Attachment) GetStoragePath() string {
|
func (v Attachment) GetStoragePath() string {
|
||||||
|
@ -14,7 +14,7 @@ export default function PostAttachments(props: { attachments: any[] }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getUrl(item: any): string {
|
function getUrl(item: any): string {
|
||||||
return `/api/attachments/o/${item.file_id}`;
|
return item.external_url ?? `/api/attachments/o/${item.file_id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
@ -36,8 +36,8 @@ export default function PostAttachments(props: { attachments: any[] }) {
|
|||||||
<i class="fa-solid fa-circle-question text-3xl"></i>
|
<i class="fa-solid fa-circle-question text-3xl"></i>
|
||||||
<p class="mt-3">{item().filename}</p>
|
<p class="mt-3">{item().filename}</p>
|
||||||
|
|
||||||
<div class="flex gap-3 w-full">
|
<div class="flex gap-2 w-full">
|
||||||
<p class="text-sm">{item().filesize} Bytes</p>
|
<p class="text-sm">{item().filesize <= 0 ? "Unknown" : item().filesize} Bytes</p>
|
||||||
<p class="text-sm">{item().mimetype}</p>
|
<p class="text-sm">{item().mimetype}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -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 { getAtk, useUserinfo } from "../stores/userinfo.tsx";
|
||||||
|
|
||||||
import styles from "./PostPublish.module.css";
|
import styles from "./PostPublish.module.css";
|
||||||
@ -22,6 +22,8 @@ export default function PostPublish(props: {
|
|||||||
const [categories, setCategories] = createSignal<{ alias: string, name: string }[]>([]);
|
const [categories, setCategories] = createSignal<{ alias: string, name: string }[]>([]);
|
||||||
const [tags, setTags] = createSignal<{ alias: string, name: string }[]>([]);
|
const [tags, setTags] = createSignal<{ alias: string, name: string }[]>([]);
|
||||||
|
|
||||||
|
const [attachmentMode, setAttachmentMode] = createSignal(0);
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
setAttachments(props.editing?.attachments ?? []);
|
setAttachments(props.editing?.attachments ?? []);
|
||||||
setCategories(props.editing?.categories ?? []);
|
setCategories(props.editing?.categories ?? []);
|
||||||
@ -101,7 +103,7 @@ export default function PostPublish(props: {
|
|||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function uploadAttachments(evt: SubmitEvent) {
|
async function uploadAttachment(evt: SubmitEvent) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
const form = evt.target as HTMLFormElement;
|
const form = evt.target as HTMLFormElement;
|
||||||
@ -125,6 +127,19 @@ export default function PostPublish(props: {
|
|||||||
setUploading(false);
|
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) {
|
function addCategory(evt: SubmitEvent) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
@ -138,7 +153,7 @@ export default function PostPublish(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function removeCategory(target: any) {
|
function removeCategory(target: any) {
|
||||||
setCategories(categories().filter(item => item.alias !== target.alias))
|
setCategories(categories().filter(item => item.alias !== target.alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTag(evt: SubmitEvent) {
|
function addTag(evt: SubmitEvent) {
|
||||||
@ -154,7 +169,7 @@ export default function PostPublish(props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function removeTag(target: any) {
|
function removeTag(target: any) {
|
||||||
setTags(tags().filter(item => item.alias !== target.alias))
|
setTags(tags().filter(item => item.alias !== target.alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
function resetForm() {
|
||||||
@ -270,23 +285,60 @@ export default function PostPublish(props: {
|
|||||||
<dialog id="attachments" class="modal">
|
<dialog id="attachments" class="modal">
|
||||||
<div class="modal-box">
|
<div class="modal-box">
|
||||||
<h3 class="font-bold text-lg mx-1">Attachments</h3>
|
<h3 class="font-bold text-lg mx-1">Attachments</h3>
|
||||||
<form class="w-full mt-3" onSubmit={uploadAttachments}>
|
|
||||||
<label class="form-control">
|
<div role="tablist" class="tabs tabs-boxed mt-3">
|
||||||
<div class="label">
|
<input type="radio" name="attachment" role="tab" class="tab" aria-label="File picker"
|
||||||
<span class="label-text">Pick a file</span>
|
checked={attachmentMode() === 0} onClick={() => setAttachmentMode(0)} />
|
||||||
</div>
|
<input type="radio" name="attachment" role="tab" class="tab" aria-label="External link"
|
||||||
<div class="join">
|
checked={attachmentMode() === 1} onClick={() => setAttachmentMode(1)} />
|
||||||
<input required type="file" name="attachment"
|
</div>
|
||||||
class="join-item file-input file-input-bordered w-full" />
|
|
||||||
<button type="submit" class="join-item btn btn-primary" disabled={uploading()}>
|
<Switch>
|
||||||
<i class="fa-solid fa-upload"></i>
|
<Match when={attachmentMode() === 0}>
|
||||||
</button>
|
<form class="w-full mt-2" onSubmit={uploadAttachment}>
|
||||||
</div>
|
<label class="form-control">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
<span class="label-text-alt">Click upload to add this file into list</span>
|
<span class="label-text">Pick a file</span>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
<div class="join">
|
||||||
</form>
|
<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}>
|
<Show when={attachments().length > 0}>
|
||||||
<h3 class="font-bold mt-3 mx-1">Attachment list</h3>
|
<h3 class="font-bold mt-3 mx-1">Attachment list</h3>
|
||||||
|
@ -11,7 +11,8 @@ interface MenuItem {
|
|||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
const nav: MenuItem[] = [
|
const nav: MenuItem[] = [
|
||||||
{ label: "Feed", href: "/" }
|
{ label: "Feed", href: "/" },
|
||||||
|
{ label: "Realms", href: "/realms" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const wellKnown = useWellKnown();
|
const wellKnown = useWellKnown();
|
||||||
|
Loading…
Reference in New Issue
Block a user