feat(frontend): add genre display UI and enhance link component

- Anime.svelte: Add genre display section with clickable badges that link
  to AniList search results for each genre. Genres are now displayed above
  the existing tags section with consistent styling.

- WebsiteLink.svelte: Enhance component to support custom URLs via the `url`
  export parameter. Previously, the component only generated URLs based on
  service prefixes (a-, m-, s-). Now it accepts a direct URL parameter for
  flexible linking to AniList searches and other external resources.

These changes provide users with an improved browsing experience by making
genres interactive and easily searchable.
This commit is contained in:
2026-03-19 20:37:12 -04:00
parent 4400dfd637
commit f4382304df
2 changed files with 51 additions and 25 deletions

View File

@@ -6,7 +6,12 @@
} from "../helperModules/GlobalVariablesAndHelperFunctions.svelte"; } from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
import {userStore} from "../helperFunctions/userStore" import {userStore} from "../helperFunctions/userStore"
import { push } from "svelte-spa-router"; import { push } from "svelte-spa-router";
<<<<<<< HEAD
import type { AniListGetSingleAnime } from "../types/AniListCurrentUserWatchListType"; import type { AniListGetSingleAnime } from "../types/AniListCurrentUserWatchListType";
=======
import WebsiteLink from "./WebsiteLink.svelte";
import type { AniListGetSingleAnime } from "../anilist/types/AniListCurrentUserWatchListType";
>>>>>>> a222c6b (feat(frontend): add genre display UI and enhance link component)
import Rating from "./Rating.svelte"; import Rating from "./Rating.svelte";
import { import {
convertAniListDateToString, convertAniListDateToString,
@@ -38,7 +43,7 @@
} from "../../wailsjs/go/main/App"; } from "../../wailsjs/go/main/App";
import { AddAnimeServiceToTable } from "../helperModules/AddAnimeServiceToTable.svelte"; import { AddAnimeServiceToTable } from "../helperModules/AddAnimeServiceToTable.svelte";
import Datepicker from "./Datepicker.svelte"; import Datepicker from "./Datepicker.svelte";
import {Badge, Tooltip} from "flowbite-svelte"; import { Badge, Tooltip } from "flowbite-svelte";
const re = /^([0-9]{4})-([0-9]{2})-([0-9]{2})/; const re = /^([0-9]{4})-([0-9]{2})-([0-9]{2})/;
let currentAniListAnime: AniListGetSingleAnime; let currentAniListAnime: AniListGetSingleAnime;
@@ -817,15 +822,32 @@
<div class="flex m-5"> <div class="flex m-5">
<div> <div>
<h3 class="text-2xl">Genres</h3>
{#each currentAniListAnime.data.MediaList.media.genres as genre}
<div>
<Badge large border color="blue" class="m-1 w-52">
<div>
<WebsiteLink
id={genre}
url="https://anilist.co/search/anime/{genre}"
/>
</div>
</Badge>
<Tooltip>{genre}</Tooltip>
</div>
{/each}
<h3 class="text-2xl">Tags</h3> <h3 class="text-2xl">Tags</h3>
<div class="mt-2"> <div class="mt-2">
{#each currentAniListAnime.data.MediaList.media.tags as tag} {#each currentAniListAnime.data.MediaList.media.tags as tag}
<div> <div>
<Badge large border color="blue" class="m-1 w-52"> <Badge large border color="blue" class="m-1 w-52">
<div> <div>
{tag.name} - <WebsiteLink
<span class="text-xs">{tag.rank}%</span> id={tag.name}
</div> url="https://anilist.co/search/anime/?genres={tag.name}"
/>
<span class="text-xs">({tag.rank}%)</span>
</div>
</Badge> </Badge>
<Tooltip>{tag.description}</Tooltip> <Tooltip>{tag.description}</Tooltip>
</div> </div>

View File

@@ -1,28 +1,32 @@
<script lang="ts"> <script lang="ts">
import {BrowserOpenURL} from "../../wailsjs/runtime" import { BrowserOpenURL } from "../../wailsjs/runtime";
export let id: string export let id: string;
let url = "" export let url = "";
let isAniList = false let isAniList = false;
let isMAL = false let isMAL = false;
let isSimkl = false let isSimkl = false;
let newId = id let newId = id;
let re = /[ams]?-?(.*)/ let re = /[ams]?-?(.*)/;
if (id !== undefined && id.length > 0) { if (id !== undefined && id.length > 0) {
isAniList = id.includes("a-") isAniList = id.includes("a-");
isMAL = id.includes("m-") isMAL = id.includes("m-");
isSimkl = id.includes("s-") isSimkl = id.includes("s-");
newId = id.match(re)[1] if (isAniList || isMAL || isSimkl) newId = id.match(re)[1];
} else newId = id;
}
if (isAniList) url = `https://anilist.co/anime/${newId}`;
if (isAniList) url = `https://anilist.co/anime/${newId}` if (isMAL) url = `https://myanimelist.net/anime/${newId}`;
if (isMAL) url = `https://myanimelist.net/anime/${newId}` if (isSimkl) url = `https://simkl.com/anime/${newId}`;
if (isSimkl) url = `https://simkl.com/anime/${newId}`
</script> </script>
{#if url.length > 0} {#if url.length > 0}
<button class="underline underline-offset-2 px-4 py-1" on:click={() => BrowserOpenURL(url)}>{newId}</button> <button
type="button"
class="underline underline-offset-2 px-4 py-1"
on:click={() => BrowserOpenURL(url)}>{newId}</button
>
{:else} {:else}
{id} {id}
{/if} {/if}