mirror of
https://github.com/Damillora/phoebe.git
synced 2025-03-10 05:57:22 +00:00
feat: another UI change
This commit is contained in:
parent
4c2fb159a9
commit
1fd9e364bb
@ -112,6 +112,7 @@ func postGetOne(c *gin.Context) {
|
||||
Width: post.Blob.Width,
|
||||
Height: post.Blob.Height,
|
||||
Uploader: post.User.Username,
|
||||
UploadDate: post.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type PostReadModel struct {
|
||||
ID string `json:"id"`
|
||||
ImagePreviewPath string `json:"preview_path"`
|
||||
@ -9,6 +11,7 @@ type PostReadModel struct {
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Uploader string `json:"uploader"`
|
||||
UploadDate time.Time `json:"upload_date"`
|
||||
}
|
||||
|
||||
type TagReadModel struct {
|
||||
|
11
pkg/web/package-lock.json
generated
11
pkg/web/package-lock.json
generated
@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"bulma": "^1.0.3",
|
||||
"date-fns": "^4.1.0",
|
||||
"query-string": "^8.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -1853,6 +1854,16 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
|
||||
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
|
@ -30,6 +30,7 @@
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"bulma": "^1.0.3",
|
||||
"date-fns": "^4.1.0",
|
||||
"query-string": "^8.1.0"
|
||||
}
|
||||
}
|
||||
|
38
pkg/web/src/lib/components/panels/DeletePostPanel.svelte
Normal file
38
pkg/web/src/lib/components/panels/DeletePostPanel.svelte
Normal file
@ -0,0 +1,38 @@
|
||||
<script>
|
||||
import { postDelete } from "$lib/api";
|
||||
|
||||
let { id, toggleDeleteMenu, onDelete } = $props();
|
||||
let deleteLoading = $state(false);
|
||||
|
||||
const deletePost = async (e) => {
|
||||
e.preventDefault();
|
||||
deleteLoading = true;
|
||||
const success = await postDelete({ id });
|
||||
deleteLoading = false;
|
||||
toggleDeleteMenu(e);
|
||||
onDelete(success);
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="block">
|
||||
<div class="panel is-danger">
|
||||
<p class="panel-heading">Delete Post</p>
|
||||
{#if !deleteLoading}
|
||||
<div class="panel-block">
|
||||
Are you sure to delete post {id}?
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<button onclick={deletePost} class="button is-danger"
|
||||
>Delete</button
|
||||
>
|
||||
<button class="button" onclick={toggleDeleteMenu}>Cancel</button
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="panel-block column">
|
||||
<progress class="progress is-small is-danger" max="100"
|
||||
></progress>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
@ -11,6 +11,8 @@
|
||||
|
||||
let { isActive = $bindable(false), post, onSubmit }: Props = $props();
|
||||
|
||||
let editLoading = $state(false);
|
||||
|
||||
const toggleEditModal = (e) => {
|
||||
e.preventDefault();
|
||||
isActive = !isActive;
|
||||
@ -37,9 +39,10 @@
|
||||
|
||||
const onFormSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
editLoading = true;
|
||||
const response = await postUpdate(post.id, form);
|
||||
toggleEditModal();
|
||||
|
||||
editLoading = false;
|
||||
toggleEditModal(e);
|
||||
onSubmit();
|
||||
};
|
||||
|
||||
@ -51,6 +54,7 @@
|
||||
<form onsubmit={onFormSubmit}>
|
||||
<div class="panel is-warning">
|
||||
<p class="panel-heading">Edit Post</p>
|
||||
{#if !editLoading}
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<strong>Uploader:</strong>
|
||||
@ -115,5 +119,10 @@
|
||||
>Cancel</button
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="panel-block column">
|
||||
<progress class="progress is-small is-warning" max="100"></progress>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
|
@ -2,16 +2,12 @@
|
||||
import { onMount } from "svelte";
|
||||
import { updateTagNotes } from "$lib/api";
|
||||
|
||||
let {
|
||||
tag,
|
||||
data,
|
||||
toggleEditMenu,
|
||||
onSubmit
|
||||
} = $props();
|
||||
let { tag, data, toggleEditMenu, onSubmit } = $props();
|
||||
|
||||
let form = $state({
|
||||
note: "",
|
||||
});
|
||||
let editNotesLoading = $state(false);
|
||||
|
||||
const getData = async () => {
|
||||
form.note = data.tagNote;
|
||||
@ -19,7 +15,9 @@
|
||||
|
||||
const onFormSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
editNotesLoading = true;
|
||||
await updateTagNotes(tag, form);
|
||||
editNotesLoading = false;
|
||||
toggleEditMenu();
|
||||
|
||||
onSubmit();
|
||||
@ -33,18 +31,21 @@
|
||||
<form onsubmit={onFormSubmit}>
|
||||
<div class="panel is-warning">
|
||||
<p class="panel-heading">Edit Notes</p>
|
||||
{#if !editNotesLoading}
|
||||
<div class="panel-block column">
|
||||
<textarea
|
||||
bind:value={form.note}
|
||||
class="textarea has-fixed-size"
|
||||
></textarea>
|
||||
<textarea bind:value={form.note} class="textarea has-fixed-size"
|
||||
></textarea>
|
||||
<div class="content"></div>
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<button type="submit" class="button is-primary">Save</button>
|
||||
<button onclick={toggleEditMenu} class="button"
|
||||
>Cancel</button
|
||||
>
|
||||
<button onclick={toggleEditMenu} class="button">Cancel</button>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="panel-block column">
|
||||
<progress class="progress is-small is-warning" max="100"
|
||||
></progress>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
|
@ -2,19 +2,16 @@
|
||||
import { onMount } from "svelte";
|
||||
|
||||
import { getTagTypes, updateTag } from "$lib/api";
|
||||
import { goto } from "$app/navigation";
|
||||
|
||||
let {
|
||||
tag,
|
||||
data,
|
||||
toggleRenameMenu,
|
||||
onSubmit
|
||||
} = $props();
|
||||
let { tag, data, toggleRenameMenu, onSubmit } = $props();
|
||||
|
||||
let tagTypes = $state([]);
|
||||
let form = $state({
|
||||
name: "",
|
||||
tagTypeId: 1,
|
||||
});
|
||||
let editTagLoading = $state(false);
|
||||
|
||||
const getData = async () => {
|
||||
tagTypes = await getTagTypes();
|
||||
@ -25,10 +22,9 @@
|
||||
|
||||
const onFormSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
editTagLoading = true;
|
||||
await updateTag(tag, form);
|
||||
|
||||
goto("/tags/" + form.name);
|
||||
|
||||
editTagLoading = false;
|
||||
onSubmit(form.name);
|
||||
};
|
||||
|
||||
@ -40,6 +36,7 @@
|
||||
<form onsubmit={onFormSubmit}>
|
||||
<div class="panel is-warning">
|
||||
<p class="panel-heading">Edit Tag</p>
|
||||
{#if !editTagLoading}
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<strong>Name:</strong>
|
||||
@ -77,19 +74,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<strong>Posts:</strong>
|
||||
</div>
|
||||
<div class="row">
|
||||
{data.postCount} (<a href="/posts?tags={tag}">Browse</a>)
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<button class="button is-primary" type="submit">Submit</button>
|
||||
<button onclick={toggleRenameMenu} class="button"
|
||||
>Cancel</button
|
||||
<button onclick={toggleRenameMenu} class="button">Cancel</button
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="panel-block column">
|
||||
<progress class="progress is-small is-warning" max="100"
|
||||
></progress>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,8 +1,14 @@
|
||||
<script lang="ts">
|
||||
import AuthCheck from "$lib/components/checks/AuthCheck.svelte";
|
||||
import TagLinkNumbered from "$lib/components/ui/TagLinkNumbered.svelte";
|
||||
let { post, toggleEditMenu, toggleDeleteMenu } = $props();
|
||||
import { format, formatDistanceToNow } from "date-fns";
|
||||
let { post } = $props();
|
||||
|
||||
let tabPage = $state(1);
|
||||
|
||||
const changeTab = (tab) => {
|
||||
tabPage = tab;
|
||||
}
|
||||
const trimUrl = (str) => {
|
||||
if (str.length > 30) {
|
||||
return str.substring(0, 30) + "...";
|
||||
@ -13,6 +19,27 @@
|
||||
|
||||
<div class="panel is-primary">
|
||||
<p class="panel-heading">Post</p>
|
||||
<div class="panel-tabs">
|
||||
<a href={"#"} class:is-active="{tabPage == 1}" onclick={() => changeTab(1)}>Tags</a>
|
||||
<a href={"#"} class:is-active="{tabPage == 2}" onclick={() => changeTab(2)}>Information</a>
|
||||
</div>
|
||||
{#if tabPage === 1}
|
||||
|
||||
{#if post.tags}
|
||||
{#each post.tags as tag (tag)}
|
||||
<TagLinkNumbered
|
||||
tag={tag.tagType + ":" + tag.tagName}
|
||||
num={tag.postCount}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
||||
{:else if tabPage == 2}
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<strong>Upload Date:</strong>
|
||||
</div>
|
||||
<div class="row"><time title={format(post.upload_date, "dd MMMM yyyy HH:mm:ss")} datetime={post.upload_date} >{formatDistanceToNow(post.upload_date, {addSuffix: true })}</time></div>
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<strong>Uploader:</strong>
|
||||
@ -43,38 +70,5 @@
|
||||
<a href={post.source_url}>{trimUrl(post.source_url)}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<p><strong>Tags:</strong></p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="menu">
|
||||
<ul class="menu-list">
|
||||
{#if post.tags}
|
||||
{#each post.tags as tag (tag)}
|
||||
<li>
|
||||
<TagLinkNumbered
|
||||
class=""
|
||||
tag={tag.tagType + ":" + tag.tagName}
|
||||
num={tag.postCount}
|
||||
/>
|
||||
</li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AuthCheck>
|
||||
<p class="panel-block column">
|
||||
<button
|
||||
onclick={toggleEditMenu}
|
||||
class="button is-primary">Edit</button
|
||||
>
|
||||
<button
|
||||
onclick={toggleDeleteMenu}
|
||||
class="button is-danger">Delete</button
|
||||
>
|
||||
</p>
|
||||
</AuthCheck>
|
||||
</div>
|
||||
|
@ -8,6 +8,12 @@
|
||||
|
||||
let { tag, data, toggleRenameMenu } = $props();
|
||||
let related_tags = $state([]);
|
||||
|
||||
let tabPage = $state(1);
|
||||
|
||||
const changeTab = (tab) => {
|
||||
tabPage = tab;
|
||||
};
|
||||
const getData = async () => {
|
||||
related_tags = await getRelatedTags({ tag });
|
||||
related_tags = related_tags
|
||||
@ -21,6 +27,19 @@
|
||||
|
||||
<div class="panel is-primary">
|
||||
<p class="panel-heading">Tag</p>
|
||||
<div class="panel-tabs">
|
||||
<a
|
||||
href={"#"}
|
||||
class:is-active={tabPage == 1}
|
||||
onclick={() => changeTab(1)}>Information</a
|
||||
>
|
||||
<a
|
||||
href={"#"}
|
||||
class:is-active={tabPage == 2}
|
||||
onclick={() => changeTab(2)}>Related Tags</a
|
||||
>
|
||||
</div>
|
||||
{#if tabPage === 1}
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<strong>Name:</strong>
|
||||
@ -38,35 +57,15 @@
|
||||
<strong>Posts:</strong>
|
||||
</div>
|
||||
<div class="row">
|
||||
{data.postCount} (<a href="/posts?tags={tag}">Browse</a>)
|
||||
{data.postCount}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<strong>Related Tags:</strong>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="menu">
|
||||
<ul class="menu-list">
|
||||
{:else if tabPage === 2}
|
||||
{#each related_tags as tag (tag)}
|
||||
<li>
|
||||
<TagLinkNumbered
|
||||
class=""
|
||||
tag={tag.tagType + ":" + tag.tagName}
|
||||
num={tag.postCount}
|
||||
/>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AuthCheck>
|
||||
<div class="panel-block column">
|
||||
<button
|
||||
onclick={toggleRenameMenu}
|
||||
class="button is-primary">Rename</button
|
||||
>
|
||||
</div>
|
||||
</AuthCheck>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -8,10 +8,10 @@
|
||||
let tagDisplay = tagName.split("_").join(" ");
|
||||
</script>
|
||||
|
||||
<a href="/posts?tags={tagName}">
|
||||
<a class="panel-block is-block" href="/posts?tags={tagName}">
|
||||
<span>
|
||||
{tagDisplay}
|
||||
</span>
|
||||
<TagTypeIndicator tagType={tagType}></TagTypeIndicator>
|
||||
<TagTypeIndicator {tagType}></TagTypeIndicator>
|
||||
<span class="is-pulled-right">{num}</span>
|
||||
</a>
|
||||
|
@ -7,15 +7,17 @@
|
||||
|
||||
import { page } from "$app/stores";
|
||||
import ShiorikoImage from "$lib/components/ui/ShiorikoImage.svelte";
|
||||
import AuthCheck from "$lib/components/checks/AuthCheck.svelte";
|
||||
import DeletePostPanel from "$lib/components/panels/DeletePostPanel.svelte";
|
||||
const { id } = $page.params;
|
||||
|
||||
let post: any = $state();
|
||||
const getData = async () => {
|
||||
post = null;
|
||||
const data = await getPost({ id });
|
||||
post = data;
|
||||
imagePercentage = ((1000 * 100) / post.width).toFixed(0) + "%";
|
||||
};
|
||||
let loading = $state(false);
|
||||
let isOriginal = $state(false);
|
||||
|
||||
const trimUrl = (str: string) => {
|
||||
@ -25,25 +27,22 @@
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
let deleteMenuShown = $state(false);
|
||||
|
||||
const onSubmitEdit = () => {
|
||||
getData();
|
||||
editMenuShown = false;
|
||||
}
|
||||
};
|
||||
onMount(() => {
|
||||
getData();
|
||||
});
|
||||
|
||||
const deletePost = async (e) => {
|
||||
e.preventDefault();
|
||||
toggleDeleteMenu(e);
|
||||
const success = await postDelete({ id });
|
||||
const onDelete = async (success) => {
|
||||
if (success) {
|
||||
goto("/posts");
|
||||
}
|
||||
};
|
||||
|
||||
const toggleDeleteMenu = (e) => {
|
||||
e.preventDefault();
|
||||
deleteMenuShown = !deleteMenuShown;
|
||||
@ -64,68 +63,85 @@
|
||||
<div class="columns">
|
||||
<div class="column is-one-third">
|
||||
{#if post}
|
||||
{#if editMenuShown == false && deleteMenuShown == false}
|
||||
<ViewPostPanel
|
||||
{post}
|
||||
{toggleDeleteMenu}
|
||||
{toggleEditMenu}
|
||||
/>
|
||||
{:else if editMenuShown == true}
|
||||
<div class="block">
|
||||
<ViewPostPanel {post} />
|
||||
</div>
|
||||
{#if editMenuShown == true && deleteMenuShown == false}
|
||||
<div class="block">
|
||||
<EditPostPanel
|
||||
bind:isActive={editMenuShown}
|
||||
{post}
|
||||
onSubmit={onSubmitEdit}
|
||||
/>
|
||||
</div>
|
||||
{:else if deleteMenuShown == true}
|
||||
<div class="panel is-danger">
|
||||
<p class="panel-heading">Delete Post</p>
|
||||
<div class="panel-block">
|
||||
Are you sure to delete post {post.id}?
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
<button
|
||||
onclick={deletePost}
|
||||
class="button is-danger">Delete</button
|
||||
<DeletePostPanel
|
||||
id={post.id}
|
||||
{toggleDeleteMenu}
|
||||
{onDelete}
|
||||
/>
|
||||
{:else}
|
||||
<AuthCheck>
|
||||
<div class="panel is-info">
|
||||
<div class="panel-heading">Post Actions</div>
|
||||
|
||||
<a
|
||||
class="panel-block"
|
||||
href={post.image_path}
|
||||
target="_blank">View Original</a
|
||||
>
|
||||
<button
|
||||
class="button"
|
||||
onclick={toggleDeleteMenu}>Cancel</button
|
||||
<a
|
||||
href={"#"}
|
||||
onclick={toggleEditMenu}
|
||||
class="panel-block">Edit</a
|
||||
>
|
||||
<a
|
||||
href={"#"}
|
||||
onclick={toggleDeleteMenu}
|
||||
class="panel-block">Delete</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</AuthCheck>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="skeleton-block"></div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="column box">
|
||||
<div class="column is-two-thirds">
|
||||
{#if post}
|
||||
<div class="block">
|
||||
{#if post.width > 1000 && isOriginal == false}
|
||||
<div class="notification is-info">
|
||||
Resized to {imagePercentage} of the original image.
|
||||
<a
|
||||
href={"#"}
|
||||
onclick={() => {
|
||||
isOriginal = true;
|
||||
}}>View original</a
|
||||
>
|
||||
</div>
|
||||
<div class="box">
|
||||
<figure class="image">
|
||||
<ShiorikoImage
|
||||
alt={post.id}
|
||||
src={post.preview_path}
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="notification is-primary">
|
||||
Currently viewing original image.
|
||||
</div>
|
||||
<div class="box">
|
||||
<figure class="image">
|
||||
<ShiorikoImage
|
||||
alt={post.id}
|
||||
src={post.image_path}
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="skeleton-block"></div>
|
||||
{/if}
|
||||
|
@ -127,33 +127,18 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="panel-block column">
|
||||
{#if !loading}
|
||||
<div class="row">
|
||||
<strong>Tags:</strong>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="menu">
|
||||
<ul class="menu-list">
|
||||
{#each tags as tag (tag)}
|
||||
<li>
|
||||
<TagLinkNumbered
|
||||
class=""
|
||||
tag={tag.tagType +
|
||||
":" +
|
||||
tag.tagName}
|
||||
tag={tag.tagType + ":" + tag.tagName}
|
||||
num={tag.postCount}
|
||||
/>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="skeleton-block"></div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if tagInfo}
|
||||
<div class="panel is-info">
|
||||
<p class="panel-heading">
|
||||
|
@ -1,26 +1,30 @@
|
||||
<script>
|
||||
import { run } from 'svelte/legacy';
|
||||
import { run } from "svelte/legacy";
|
||||
|
||||
import { getTags } from "$lib/api";
|
||||
import { afterNavigate } from '$app/navigation';
|
||||
import TagTypeIndicator from '$lib/components/ui/TagTypeIndicator.svelte';
|
||||
import { afterNavigate } from "$app/navigation";
|
||||
import TagTypeIndicator from "$lib/components/ui/TagTypeIndicator.svelte";
|
||||
|
||||
let tags = $state([]);
|
||||
let loading = $state(false);
|
||||
let highestCount = $state(1);
|
||||
|
||||
const getData = async () => {
|
||||
const data = await getTags();
|
||||
tags = data;
|
||||
loading = false;
|
||||
highestCount = Math.max(...data.map((x) => x.postCount));
|
||||
if (highestCount <= 0) {
|
||||
highestCount = 1;
|
||||
}
|
||||
};
|
||||
|
||||
afterNavigate(() => {
|
||||
loading = true;
|
||||
getData();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">Tag List</h1>
|
||||
@ -28,19 +32,26 @@
|
||||
<table class="table is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th >Tag</th>
|
||||
<th style="width: 30%;">Tag Type</th>
|
||||
<th style="width: 10%;">Post Count</th>
|
||||
<th>Tag</th>
|
||||
<th>Post Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each tags as tag}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="/tags/{tag.tagName}">{tag.tagName}</a>
|
||||
<a href="/tags/{tag.tagName}"
|
||||
>{tag.tagName}
|
||||
<TagTypeIndicator
|
||||
tagType={tag.tagType}
|
||||
/></a
|
||||
>
|
||||
</td>
|
||||
<td><TagTypeIndicator tagType={tag.tagType} /></td>
|
||||
<td>{tag.postCount}</td>
|
||||
<td>
|
||||
<span class="is-pulled-right"
|
||||
>{tag.postCount}</span
|
||||
></td
|
||||
>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
|
@ -9,6 +9,7 @@
|
||||
import PostGallery from "$lib/components/ui/PostGallery.svelte";
|
||||
|
||||
import { page } from "$app/stores";
|
||||
import AuthCheck from "$lib/components/checks/AuthCheck.svelte";
|
||||
let { tag } = $state($page.params);
|
||||
|
||||
let data = $state();
|
||||
@ -16,6 +17,7 @@
|
||||
|
||||
const getData = async () => {
|
||||
if (tag) {
|
||||
data = null;
|
||||
data = await getTag({ tag });
|
||||
const response = await getPosts({
|
||||
page: 1,
|
||||
@ -40,6 +42,7 @@
|
||||
|
||||
const onTagSubmit = (newName) => {
|
||||
tag = newName;
|
||||
toggleEditMenu();
|
||||
getData();
|
||||
};
|
||||
|
||||
@ -53,15 +56,28 @@
|
||||
<div class="columns">
|
||||
<div class="column is-one-third">
|
||||
{#if data}
|
||||
<div class="block">
|
||||
<ViewTagPanel {tag} {data} />
|
||||
</div>
|
||||
{#if renameMenuShown}
|
||||
<div class="block">
|
||||
<EditTagPanel
|
||||
{tag}
|
||||
{data}
|
||||
{toggleRenameMenu}
|
||||
onSubmit={onTagSubmit}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<ViewTagPanel {tag} {data} {toggleRenameMenu} />
|
||||
<AuthCheck>
|
||||
<div class="panel is-info">
|
||||
<div class="panel-heading">Tag Actions</div>
|
||||
<a class="panel-block" href="/posts?tags={tag}">Browse Posts</a>
|
||||
<a onclick={toggleRenameMenu} class="panel-block"
|
||||
>Rename</a
|
||||
>
|
||||
</div>
|
||||
</AuthCheck>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="skeleton-block"></div>
|
||||
|
@ -10,6 +10,7 @@
|
||||
let fileName = $state("");
|
||||
let similar = $state([]);
|
||||
let previewUrl = $state("");
|
||||
let loading = $state(false);
|
||||
|
||||
let form = $state({
|
||||
blob_id: "",
|
||||
@ -23,6 +24,7 @@
|
||||
};
|
||||
|
||||
const onFileChange = async (e) => {
|
||||
loading = true;
|
||||
var file = e.target.files[0];
|
||||
fileName = "";
|
||||
previewUrl = "";
|
||||
@ -38,6 +40,7 @@
|
||||
fileName = file.name;
|
||||
previewUrl = response.previewUrl;
|
||||
}
|
||||
loading = false;
|
||||
};
|
||||
|
||||
const onTagChange = (value) => {
|
||||
@ -94,6 +97,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if currentProgress > 0 && currentProgress < 100}
|
||||
<div class="panel-block column">
|
||||
<progress
|
||||
class="progress is-primary is-small"
|
||||
value={currentProgress}
|
||||
max="100"
|
||||
>
|
||||
{currentProgress}%
|
||||
</progress>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="panel-block column">
|
||||
<div class="row">
|
||||
<label for="source" class="label"
|
||||
@ -143,7 +157,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-two-thirds">
|
||||
<div class="box">
|
||||
<div class="block">
|
||||
{#if fileName}
|
||||
{#if similar.length > 0}
|
||||
<div class="notification is-warning">
|
||||
@ -157,21 +171,11 @@
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="notification is-primary">
|
||||
<div class="notification is-success">
|
||||
{fileName} has been succesfully uploaded.
|
||||
</div>
|
||||
{/if}
|
||||
<figure class="image">
|
||||
<ShiorikoImage alt={fileName} src={previewUrl} />
|
||||
</figure>
|
||||
{:else if currentProgress > 0 && currentProgress < 100}
|
||||
<progress
|
||||
class="progress is-primary"
|
||||
value={currentProgress}
|
||||
max="100"
|
||||
>
|
||||
{currentProgress}%
|
||||
</progress>
|
||||
<div class="notification is-info">
|
||||
Your image is currently uploading...
|
||||
</div>
|
||||
@ -181,6 +185,15 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if fileName}
|
||||
<div class="box">
|
||||
<figure class="image">
|
||||
<ShiorikoImage alt={fileName} src={previewUrl} />
|
||||
</figure>
|
||||
</div>
|
||||
{:else if loading && !(currentProgress > 0 && currentProgress < 100)}
|
||||
<div class="skeleton-block"></div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user