mirror of
https://github.com/koloml/furbooru-tagging-assistant.git
synced 2025-12-24 15:12:58 +00:00
First draft version with Svelte for popup and additional build steps
This commit is contained in:
1
src/routes/+layout.server.js
Normal file
1
src/routes/+layout.server.js
Normal file
@@ -0,0 +1 @@
|
||||
export const ssr = false;
|
||||
17
src/routes/+layout.svelte
Normal file
17
src/routes/+layout.svelte
Normal file
@@ -0,0 +1,17 @@
|
||||
<script>
|
||||
import "../styles/popup.scss";
|
||||
import Header from "$components/layout/Header.svelte";
|
||||
import Footer from "$components/layout/Footer.svelte";
|
||||
</script>
|
||||
|
||||
<Header/>
|
||||
<main>
|
||||
<slot/>
|
||||
</main>
|
||||
<Footer/>
|
||||
|
||||
<style lang="scss" global>
|
||||
main {
|
||||
padding: .5em 24px;
|
||||
}
|
||||
</style>
|
||||
1
src/routes/+page.server.js
Normal file
1
src/routes/+page.server.js
Normal file
@@ -0,0 +1 @@
|
||||
export const prerender = true;
|
||||
10
src/routes/+page.svelte
Normal file
10
src/routes/+page.svelte
Normal file
@@ -0,0 +1,10 @@
|
||||
<script>
|
||||
import Menu from "$components/ui/menu/Menu.svelte";
|
||||
import MenuLink from "$components/ui/menu/MenuLink.svelte";
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<MenuLink href="/settings/maintenance">Manual Tags Maintenance</MenuLink>
|
||||
<hr>
|
||||
<MenuLink href="/about">About</MenuLink>
|
||||
</Menu>
|
||||
25
src/routes/about/+page.svelte
Normal file
25
src/routes/about/+page.svelte
Normal file
@@ -0,0 +1,25 @@
|
||||
<script>
|
||||
import Menu from "$components/ui/menu/Menu.svelte";
|
||||
import MenuLink from "$components/ui/menu/MenuLink.svelte";
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<MenuLink icon="arrow-left" href="/">Back</MenuLink>
|
||||
<hr>
|
||||
</Menu>
|
||||
<h1>
|
||||
Furbooru Tagging Assistant
|
||||
</h1>
|
||||
<p>
|
||||
This is a tool made to help tag images on Furbooru more efficiently. It is currently in development and is not yet
|
||||
ready for use, but it still can provide some useful functionality.
|
||||
</p>
|
||||
<Menu>
|
||||
<hr>
|
||||
<MenuLink icon="globe" href="https://furbooru.org" target="_blank">
|
||||
Visit Furbooru
|
||||
</MenuLink>
|
||||
<MenuLink icon="info-circle" href="https://github.com/koloml/furbooru-tagging-assistant" target="_blank">
|
||||
GitHub Repo
|
||||
</MenuLink>
|
||||
</Menu>
|
||||
10
src/routes/settings/+page.svelte
Normal file
10
src/routes/settings/+page.svelte
Normal file
@@ -0,0 +1,10 @@
|
||||
<script>
|
||||
import Menu from "$components/ui/menu/Menu.svelte";
|
||||
import MenuLink from "$components/ui/menu/MenuLink.svelte";
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<MenuLink href="/">Back</MenuLink>
|
||||
<hr>
|
||||
<MenuLink href="/settings/maintenance">Maintenance</MenuLink>
|
||||
</Menu>
|
||||
28
src/routes/settings/maintenance/+page.svelte
Normal file
28
src/routes/settings/maintenance/+page.svelte
Normal file
@@ -0,0 +1,28 @@
|
||||
<script>
|
||||
import Menu from "$components/ui/menu/Menu.svelte";
|
||||
import MenuLink from "$components/ui/menu/MenuLink.svelte";
|
||||
import {maintenanceProfilesStore} from "$stores/maintenance-profiles-store.js";
|
||||
import {onDestroy} from "svelte";
|
||||
|
||||
/** @type {import('$lib/extension/entities/MaintenanceProfile.js').default[]} */
|
||||
let profiles = [];
|
||||
|
||||
const unsubscribeFromProfiles = maintenanceProfilesStore.subscribe(updatedProfiles => {
|
||||
profiles = updatedProfiles.sort(
|
||||
(a, b) => b.settings.name.localeCompare(a.settings.name)
|
||||
);
|
||||
});
|
||||
|
||||
onDestroy(unsubscribeFromProfiles);
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<MenuLink icon="arrow-left" href="/">Back</MenuLink>
|
||||
<MenuLink icon="plus" href="/settings/maintenance/new/edit">Create New</MenuLink>
|
||||
{#if profiles.length}
|
||||
<hr>
|
||||
{/if}
|
||||
{#each profiles as profile}
|
||||
<MenuLink href="/settings/maintenance/{profile.id}">{profile.settings.name}</MenuLink>
|
||||
{/each}
|
||||
</Menu>
|
||||
61
src/routes/settings/maintenance/[id]/+page.svelte
Normal file
61
src/routes/settings/maintenance/[id]/+page.svelte
Normal file
@@ -0,0 +1,61 @@
|
||||
<script>
|
||||
import Menu from "$components/ui/menu/Menu.svelte";
|
||||
import MenuLink from "$components/ui/menu/MenuLink.svelte";
|
||||
import {page} from "$app/stores";
|
||||
import {goto} from "$app/navigation";
|
||||
|
||||
import {onDestroy} from "svelte";
|
||||
import {maintenanceProfilesStore} from "$stores/maintenance-profiles-store.js";
|
||||
|
||||
const profileId = $page.params.id;
|
||||
/** @type {import('$lib/extension/entities/MaintenanceProfile.js').default|null} */
|
||||
let profile = null;
|
||||
|
||||
if (profileId === 'new') {
|
||||
goto('/maintenance/profiles/new/edit');
|
||||
}
|
||||
|
||||
const unsubscribeFromProfiles = maintenanceProfilesStore.subscribe(profiles => {
|
||||
const resolvedProfile = profiles.find(p => p.id === profileId);
|
||||
|
||||
if (resolvedProfile) {
|
||||
profile = resolvedProfile;
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn(`Profile ${profileId} not found.`);
|
||||
goto('/settings/maintenance');
|
||||
});
|
||||
|
||||
onDestroy(unsubscribeFromProfiles);
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<MenuLink href="/settings/maintenance" icon="arrow-left">Back</MenuLink>
|
||||
<hr>
|
||||
</Menu>
|
||||
{#if profile}
|
||||
<div>
|
||||
<strong>Profile:</strong><br>
|
||||
{profile.settings.name}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Focused Tags:</strong>
|
||||
<div class="tags-list">
|
||||
{#each profile.settings.tags as tagName}
|
||||
<span class="tag">{tagName}</span>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<Menu>
|
||||
<hr>
|
||||
<MenuLink icon="wrench" href="/settings/maintenance/{profileId}/edit">Edit Profile</MenuLink>
|
||||
</Menu>
|
||||
<style>
|
||||
.tags-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
</style>
|
||||
80
src/routes/settings/maintenance/[id]/edit/+page.svelte
Normal file
80
src/routes/settings/maintenance/[id]/edit/+page.svelte
Normal file
@@ -0,0 +1,80 @@
|
||||
<script>
|
||||
import Menu from "$components/ui/menu/Menu.svelte";
|
||||
import MenuLink from "$components/ui/menu/MenuLink.svelte";
|
||||
import TagsEditor from "$components/web-components/TagsEditor.svelte";
|
||||
import FormControl from "$components/ui/forms/FormControl.svelte";
|
||||
import TextField from "$components/ui/forms/TextField.svelte";
|
||||
import FormContainer from "$components/ui/forms/FormContainer.svelte";
|
||||
import {page} from "$app/stores";
|
||||
import {goto} from "$app/navigation";
|
||||
import {maintenanceProfilesStore} from "$stores/maintenance-profiles-store.js";
|
||||
import MaintenanceProfile from "$entities/MaintenanceProfile.js";
|
||||
import {onDestroy} from "svelte";
|
||||
|
||||
/** @type {string} */
|
||||
let profileId = $page.params.id;
|
||||
/** @type {MaintenanceProfile|null} */
|
||||
let targetProfile = null;
|
||||
|
||||
/** @type {string} */
|
||||
let profileName = '';
|
||||
/** @type {string[]} */
|
||||
let tagsList = [];
|
||||
|
||||
const unsubscribeFromProfiles = maintenanceProfilesStore.subscribe(profiles => {
|
||||
if (profileId === 'new') {
|
||||
targetProfile = new MaintenanceProfile(crypto.randomUUID(), {});
|
||||
return;
|
||||
}
|
||||
|
||||
const maybeProfile = profiles.find(p => p.id === profileId);
|
||||
|
||||
if (!maybeProfile) {
|
||||
goto('/settings/maintenance');
|
||||
return;
|
||||
}
|
||||
|
||||
targetProfile = maybeProfile;
|
||||
|
||||
profileName = targetProfile.settings.name;
|
||||
tagsList = [...targetProfile.settings.tags];
|
||||
|
||||
queueMicrotask(() => {
|
||||
unsubscribeFromProfiles();
|
||||
})
|
||||
});
|
||||
|
||||
async function saveProfile() {
|
||||
if (!targetProfile) {
|
||||
console.warn('Attempting to save the profile, but the profile is not loaded yet.');
|
||||
return;
|
||||
}
|
||||
|
||||
targetProfile.settings.name = profileName;
|
||||
targetProfile.settings.tags = [...tagsList];
|
||||
|
||||
await targetProfile.save();
|
||||
await goto('/settings/maintenance/' + targetProfile.id);
|
||||
}
|
||||
|
||||
onDestroy(unsubscribeFromProfiles);
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<MenuLink icon="arrow-left" href="/settings/maintenance{profileId === 'new' ? '' : '/' + profileId}">
|
||||
Back
|
||||
</MenuLink>
|
||||
<hr>
|
||||
</Menu>
|
||||
<FormContainer>
|
||||
<FormControl label="Profile Name">
|
||||
<TextField bind:value={profileName} placeholder="Profile Name"></TextField>
|
||||
</FormControl>
|
||||
<FormControl label="Tags">
|
||||
<TagsEditor bind:tags={tagsList}></TagsEditor>
|
||||
</FormControl>
|
||||
</FormContainer>
|
||||
<Menu>
|
||||
<hr>
|
||||
<MenuLink href="#" on:click={saveProfile}>Save Profile</MenuLink>
|
||||
</Menu>
|
||||
Reference in New Issue
Block a user