aboutsummaryrefslogtreecommitdiff
path: root/templates
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-10-06 01:34:45 -0400
committerBobby <[email protected]>2024-10-06 01:34:45 -0400
commitbaeebfad03e243bc2598fa7cf9195a03e5d130ae (patch)
treee917fcbfa69098cbfd193135ddd232390872761e /templates
parent90ad24fbb0ae7f2bfa9b84ab1dbae296610012f8 (diff)
downloadyugen-baeebfad03e243bc2598fa7cf9195a03e5d130ae.tar.xz
yugen-baeebfad03e243bc2598fa7cf9195a03e5d130ae.zip
Manga Detail Page
Diffstat (limited to 'templates')
-rw-r--r--templates/detail/detail.html69
-rw-r--r--templates/detail/manga.html646
-rw-r--r--templates/partials/mangacard_render.html2
-rw-r--r--templates/partials/mangacardcompact_render.html2
-rw-r--r--templates/partials/mangacardwide_render.html4
-rw-r--r--templates/watch/watch.html69
6 files changed, 658 insertions, 134 deletions
diff --git a/templates/detail/detail.html b/templates/detail/detail.html
index 5f0e0c9..e410e6f 100644
--- a/templates/detail/detail.html
+++ b/templates/detail/detail.html
@@ -460,69 +460,8 @@
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2">
{% for related in related|slice:":5" %}
- {% if related.type == "MANGA" or related.type == "NOVEL" %}
- <div onClick="showToast('{% if related.type == "MANGA" %}Manga{% else %}Novel{% endif %} reading is not supported yet!', false)" class="cursor-pointer flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
- <img loading="lazy" src="{{ related.image }}" alt="{{ related.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
- <div class="flex flex-col gap-2">
- <span class="font-bold flex gap-2 flex-row items-center">
- {% if related.status == "Ongoing" %}
- <span class="text-green-500">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
- <circle cx="12" cy="12" r="12" />
- </svg>
- </span>
- {% elif related.status == "Not yet aired" %}
- <span class="text-yellow-500">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
- <circle cx="12" cy="12" r="12" />
- </svg>
- </span>
- {% else %}
- <span class="text-blue-500">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
- <circle cx="12" cy="12" r="12" />
- </svg>
- </span>
- {% endif %}
- <span>
- {% if user.preferences.title_language == "english" and related.title.english %}
- {{ related.title.english }}
- {% elif user.preferences.title_language == "native" and related.title.native %}
- {{ related.title.native }}
- {% else %}
- {{ related.title.romaji }}
- {% endif %}
- </span>
- </span>
- <span class="text-xs sm:text-sm font-bold flex gap-1 flex-row items-start">
- <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
- <svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" class="mr-1">
- <path d="M3.604 7.197l7.138 -3.109a.96 .96 0 0 1 1.27 .527l4.924 11.902a1 1 0 0 1 -.514 1.304l-7.137 3.109a.96 .96 0 0 1 -1.271 -.527l-4.924 -11.903a1 1 0 0 1 .514 -1.304z"></path>
- <path d="M15 4h1a1 1 0 0 1 1 1v3.5"></path>
- <path d="M20 6c.264 .112 .52 .217 .768 .315a1 1 0 0 1 .53 1.311l-2.298 5.374"></path>
- </svg>
- {{ related.type }}
- </span>
- <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4">
- <path d="m11.645 20.91-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z" />
- </svg>
- {{ related.relationType }}
- </span>
- {% if related.rating %}
- <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
- <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"/>
- </svg>
- {{ related.rating }}
- </span>
- {% endif %}
- </span>
- </div>
- </div>
- {% endif %}
- {% if related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" %}
- <a href="{% url 'watch:watch' related.id %}" class="flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ {% if related.id and related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" or related.type == "MANGA" or related.type == "NOVEL" %}
+ <a {% if related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" %}href="{% url 'detail:anime' related.id %}"{% elif related.type == "MANGA" %}href="{% url 'detail:manga' related.id %}"{% else %}onClick="showToast('{% if related.type == "MANGA" %}Manga{% else %}Novel{% endif %} reading is not supported yet!', false)"{% endif %} class="cursor-pointer flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
<img loading="lazy" src="{{ related.image }}" alt="{{ related.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
<div class="flex flex-col gap-2">
<span class="font-bold flex gap-2 flex-row items-center">
@@ -602,8 +541,8 @@
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2">
{% for recommendation in recommendations|slice:":10" %}
- {% if recommendation.id or recommendation.zid %}
- <a href="{% url 'watch:watch' recommendation.id %}" class="flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ {% if recommendation.id and recommendation.type == "TV" or recommendation.type == "MOVIE" or recommendation.type == "OVA" or recommendation.type == "ONA" or recommendation.type == "SPECIAL" or recommendation.type == "TV_SHORT" or recommendation.type == "MANGA" or recommendation.type == "NOVEL" %}
+ <a {% if recommendation.type == "TV" or recommendation.type == "MOVIE" or recommendation.type == "OVA" or recommendation.type == "ONA" or recommendation.type == "SPECIAL" or recommendation.type == "TV_SHORT" %}href="{% url 'detail:anime' recommendation.id %}"{% elif recommendation.type == "MANGA" %}href="{% url 'detail:manga' recommendation.id %}"{% else %}onClick="showToast('{% if related.type == "MANGA" %}Manga{% else %}Novel{% endif %} reading is not supported yet!', false)"{% endif %} class="cursor-pointer flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
<img loading="lazy" src="{{ recommendation.image }}" alt="{{ recommendation.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
<div class="flex flex-col gap-2 max-w-[calc(100%-4rem)]">
<span class="font-bold flex gap-2 flex-row items-center">
diff --git a/templates/detail/manga.html b/templates/detail/manga.html
new file mode 100644
index 0000000..ca665ec
--- /dev/null
+++ b/templates/detail/manga.html
@@ -0,0 +1,646 @@
+{% extends "partials/base.html" %}
+{% load custom_filters %}
+{% block css %}
+<style>
+ @media (max-width: 640px) {
+ .detail-section {
+ top: 0rem;
+ left: -8.5rem;
+ width: 100vw;
+ }
+
+ .w-fix {
+ position: relative;
+ left: -8rem;
+ width: calc(100vw - 1rem);
+ }
+ }
+</style>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
+{% endblock css %}
+{% block content %}
+<div style="background-image: url('{{ manga.cover }}')" class="relative bg-center bg-cover h-32 lg:h-96 my-4 rounded-lg" >
+ <div class="absolute inset-0" style="background: linear-gradient(45deg, rgb(8, 8, 8) 15%, transparent 60%), linear-gradient(0deg, rgb(8, 8, 8) 0%, transparent 60%);"></div>
+ <div class="w-4/12 lg:w-2/12 absolute px-2 lg:px-8 top-16 lg:top-48">
+ <img loading="lazy" src="{{ manga.image }}" alt="{{ manga.title.english }}" class="rounded-lg" class="w-full h-full rounded-lg object-cover"/>
+ <a href="#" class="bg-{{ user.preferences.accent_colour }}-600 hover:bg-{{ user.preferences.accent_colour }}-700 text-white text-xs sm:text-sm font-bold py-1 px-2 sm:py-2 sm:px-4 rounded-lg my-2 flex flex-row items-center justify-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4">
+ <path fill-rule="evenodd" d="M4.5 5.653c0-1.427 1.529-2.33 2.779-1.643l11.54 6.347c1.295.712 1.295 2.573 0 3.286L7.28 19.99c-1.25.687-2.779-.217-2.779-1.643V5.653Z" clip-rule="evenodd" />
+ </svg>
+ <span>Read Now</span>
+ </a>
+ <div class="flex flex-row gap-2 my-2">
+ <a href="https://anilist.co/anime/{{ manga.id }}" target="_blank" class="text-xs font-bold bg-{{ user.preferences.accent_colour }}-400 bg-opacity-30 flex-1 justify-center flex hover:bg-opacity-50 rounded px-2 py-1">
+ <svg stroke="currentColor" fill="currentColor" stroke-width="0" role="img" viewBox="0 0 24 24" height="1.5rem" width="1.5rem" xmlns="http://www.w3.org/2000/svg"><path d="M24 17.53v2.421c0 .71-.391 1.101-1.1 1.101h-5l-.057-.165L11.84 3.736c.106-.502.46-.788 1.053-.788h2.422c.71 0 1.1.391 1.1 1.1v12.38H22.9c.71 0 1.1.392 1.1 1.101zM11.034 2.947l6.337 18.104h-4.918l-1.052-3.131H6.019l-1.077 3.131H0L6.361 2.948h4.673zm-.66 10.96-1.69-5.014-1.541 5.015h3.23z"></path></svg>
+ </a>
+ <a href="https://myanimelist.net/anime/{{ manga.malId }}" target="_blank" class="ext-xs font-bold bg-{{ user.preferences.accent_colour }}-400 bg-opacity-30 flex-1 justify-center flex hover:bg-opacity-50 rounded px-2 py-1">
+ <svg stroke="currentColor" fill="currentColor" stroke-width="0" role="img" viewBox="0 0 24 24" height="1.5rem" width="1.5rem" xmlns="http://www.w3.org/2000/svg"><path d="M8.273 7.247v8.423l-2.103-.003v-5.216l-2.03 2.404-1.989-2.458-.02 5.285H.001L0 7.247h2.203l1.865 2.545 2.015-2.546 2.19.001zm8.628 2.069l.025 6.335h-2.365l-.008-2.871h-2.8c.07.499.21 1.266.417 1.779.155.381.298.751.583 1.128l-1.705 1.125c-.349-.636-.622-1.337-.878-2.082a9.296 9.296 0 0 1-.507-2.179c-.085-.75-.097-1.471.107-2.212a3.908 3.908 0 0 1 1.161-1.866c.313-.293.749-.5 1.1-.687.351-.187.743-.264 1.107-.359a7.405 7.405 0 0 1 1.191-.183c.398-.034 1.107-.066 2.39-.028l.545 1.749H14.51c-.593.008-.878.001-1.341.209a2.236 2.236 0 0 0-1.278 1.92l2.663.033.038-1.81h2.309zm3.992-2.099v6.627l3.107.032-.43 1.775h-4.807V7.187l2.13.03z"></path></svg>
+ </a>
+ </div>
+ <div class="flex flex-col">
+ <div>
+ <span class="font-bold">Format: </span>{{ manga.type }}
+ </div>
+ <div>
+ <span class="font-bold">Chapters: </span>{{ manga.chapters|length }}
+ </div>
+ <div>
+ <span class="font-bold">Year: </span>{{ manga.releaseDate }}
+ </div>
+ <div>
+ <span class="font-bold">Status: </span>{{ manga.status }}
+ </div>
+ <div>
+ <span class="font-bold">Rating: </span>{{ manga.rating }} / 100
+ </div>
+ {% if manga.studios %}
+ <div class="sm:col-span-2 lg:col-span-3">
+ <span class="font-bold">Studios: </span>
+ {% for studio in manga.studios %}
+ <span>{{ studio }}</span>{% if not forloop.last %}, {% endif %}
+ {% endfor %}
+ </div>
+ {% endif %}
+ </div>
+ </div>
+ <div class="w-8/12 lg:w-10/12 absolute top-36 lg:top-48 right-0">
+ <div class="inline-flex gap-1 sm:gap-2 flex-wrap">
+ <span {% if manga.color %}style="background-color: {{ manga.color }}3a;"{% endif %} class="text-[10px] sm:text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="size-3 sm:size-4">
+ <path d="M3.604 7.197l7.138 -3.109a.96 .96 0 0 1 1.27 .527l4.924 11.902a1 1 0 0 1 -.514 1.304l-7.137 3.109a.96 .96 0 0 1 -1.271 -.527l-4.924 -11.903a1 1 0 0 1 .514 -1.304z"></path>
+ <path d="M15 4h1a1 1 0 0 1 1 1v3.5"></path>
+ <path d="M20 6c.264 .112 .52 .217 .768 .315a1 1 0 0 1 .53 1.311l-2.298 5.374"></path>
+ </svg>
+ {{ manga.type }}
+ </span>
+ <span {% if manga.color %}style="background-color: {{ manga.color }}3a;"{% endif %} class="text-[10px] sm:text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-3 sm:size-4">
+ <path fill-rule="evenodd" d="M6.75 2.25A.75.75 0 0 1 7.5 3v1.5h9V3A.75.75 0 0 1 18 3v1.5h.75a3 3 0 0 1 3 3v11.25a3 3 0 0 1-3 3H5.25a3 3 0 0 1-3-3V7.5a3 3 0 0 1 3-3H6V3a.75.75 0 0 1 .75-.75Zm13.5 9a1.5 1.5 0 0 0-1.5-1.5H5.25a1.5 1.5 0 0 0-1.5 1.5v7.5a1.5 1.5 0 0 0 1.5 1.5h13.5a1.5 1.5 0 0 0 1.5-1.5v-7.5Z" clip-rule="evenodd" />
+ </svg>
+ {{ manga.releaseDate }}
+ </span>
+ <span {% if manga.color %}style="background-color: {{ manga.color }}3a;"{% endif %} class="text-[10px] sm:text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ {% if manga.status == "Ongoing" %}
+ <span class="text-green-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% elif manga.status == "Not yet aired" %}
+ <span class="text-yellow-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% else %}
+ <span class="text-blue-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% endif %}
+ {{ manga.status }}
+ </span>
+ <span {% if manga.color %}style="background-color: {{ manga.color }}3a;"{% endif %} class="text-[10px] sm:text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-3 sm:size-4">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"/>
+ </svg>
+ {{ manga.rating }}
+ </span>
+ <span class="text-xs sm:text-sm font-bold flex gap-2 flex-row flex-wrap items-center">
+ {% for genre in manga.genres %}
+ {% if genre == "Action" %}
+ <span class="text-xs font-bold bg-green-100 bg-opacity-20 text-green-300 py-1 px-2 rounded-full">
+ {% elif genre == "Adventure" %}
+ <span class="text-xs font-bold bg-pink-100 bg-opacity-20 text-pink-300 py-1 px-2 rounded-full">
+ {% elif genre == "Cars" %}
+ <span class="text-xs font-bold bg-orange-100 bg-opacity-20 text-orange-300 py-1 px-2 rounded-full">
+ {% elif genre == "Comedy" %}
+ <span class="text-xs font-bold bg-purple-100 bg-opacity-20 text-purple-300 py-1 px-2 rounded-full">
+ {% elif genre == "Drama" %}
+ <span class="text-xs font-bold bg-blue-100 bg-opacity-20 text-blue-300 py-1 px-2 rounded-full">
+ {% elif genre == "Fantasy" %}
+ <span class="text-xs font-bold bg-yellow-100 bg-opacity-20 text-yellow-300 py-1 px-2 rounded-full">
+ {% elif genre == "Horror" %}
+ <span class="text-xs font-bold bg-red-100 bg-opacity-20 text-red-300 py-1 px-2 rounded-full">
+ {% elif genre == "Mahou Shoujo" %}
+ <span class="text-xs font-bold bg-teal-100 bg-opacity-20 text-teal-300 py-1 px-2 rounded-full">
+ {% elif genre == "Mecha" %}
+ <span class="text-xs font-bold bg-indigo-100 bg-opacity-20 text-indigo-300 py-1 px-2 rounded-full">
+ {% elif genre == "Music" %}
+ <span class="text-xs font-bold bg-pink-100 bg-opacity-20 text-pink-300 py-1 px-2 rounded-full">
+ {% elif genre == "Mystery" %}
+ <span class="text-xs font-bold bg-purple-100 bg-opacity-20 text-purple-300 py-1 px-2 rounded-full">
+ {% elif genre == "Psychological" %}
+ <span class="text-xs font-bold bg-blue-100 bg-opacity-20 text-blue-300 py-1 px-2 rounded-full">
+ {% elif genre == "Romance" %}
+ <span class="text-xs font-bold bg-yellow-100 bg-opacity-20 text-yellow-300 py-1 px-2 rounded-full">
+ {% elif genre == "Sci-Fi" %}
+ <span class="text-xs font-bold bg-red-100 bg-opacity-20 text-red-300 py-1 px-2 rounded-full">
+ {% elif genre == "Slice of Life" %}
+ <span class="text-xs font-bold bg-teal-100 bg-opacity-20 text-teal-300 py-1 px-2 rounded-full">
+ {% elif genre == "Sports" %}
+ <span class="text-xs font-bold bg-indigo-100 bg-opacity-20 text-indigo-300 py-1 px-2 rounded-full">
+ {% elif genre == "Supernatural" %}
+ <span class="text-xs font-bold bg-green-100 bg-opacity-20 text-green-300 py-1 px-2 rounded-full">
+ {% elif genre == "Thriller" %}
+ <span class="text-xs font-bold bg-orange-100 bg-opacity-20 text-orange-300 py-1 px-2 rounded-full">
+ {% else %}
+ <span class="text-xs font-bold bg-white bg-opacity-20 text-white py-1 px-2 rounded-full">
+ {% endif %}
+ {{ genre }}
+ </span>
+ {% endfor %}
+ </span>
+ </div>
+ <h2 class="text-2xl lg:text-4xl font-bold text-transparent bg-clip-text my-2" style="background: linear-gradient(-45deg, {% if manga.color %}{{ manga.color }}{% else %}white{% endif %}, white); -webkit-background-clip: text; background-clip: text;">
+ {% if user.preferences.title_language == "english" and manga.title.english %}
+ {{ manga.title.english }}
+ {% elif user.preferences.title_language == "native" and manga.title.native %}
+ {{ manga.title.native }}
+ {% else %}
+ {{ manga.title.romaji }}
+ {% endif %}
+ </h2>
+ <p class="h-96 lg:max-h-24 overflow-auto my-2 text-sm text-white no-scrollbar">
+ {{ manga.description|strip_html }}
+ </p>
+ {% if mal_data %}
+ <section class="flex flex-col lg:flex-row gap-4 my-2 w-fix">
+ <div class="flex-1 flex flex-col gap-2">
+ <span>Update MAL Status</span>
+ <div class="relative w-full custom-select text-sm" data-select="status">
+ <div class="select-none cursor-pointer bg-neutral-900 py-2 px-4 pr-8 rounded leading-tight focus:outline-none capitalize" id="status">
+ {% if mal_data.my_list_status.status == "completed" %}
+ completed
+ {% elif mal_data.my_list_status.status == "watching" %}
+ watching
+ {% elif mal_data.my_list_status.status == "on_hold" %}
+ on hold
+ {% elif mal_data.my_list_status.status == "dropped" %}
+ dropped
+ {% elif mal_data.my_list_status.status == "plan_to_watch" %}
+ plan to watch
+ {% else %}
+ Add to List
+ {% endif %}
+ </div>
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-white">
+ <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+ <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/>
+ </svg>
+ </div>
+ <div class="absolute z-10 w-full mt-1 bg-neutral-900 rounded shadow-lg hidden max-h-96 overflow-y-scroll no-scrollbar" id="status_options">
+ <div class="py-1">
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600 capitalize" data-value="watching">watching</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600 capitalize" data-value="completed">completed</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600 capitalize" data-value="on hold">on hold</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600 capitalize" data-value="dropped">dropped</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600 capitalize" data-value="plan to watch">plan to watch</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="flex-1 flex flex-col gap-2">
+ <span>Update MAL Score</span>
+ <div class="relative w-full custom-select text-sm" data-select="score">
+ <div class="select-none cursor-pointer bg-neutral-900 py-2 px-4 pr-8 rounded leading-tight focus:outline-none" id="score">
+ {% if mal_data.my_list_status.score %}
+ {{ mal_data.my_list_status.score }}
+ {% else %}
+ Score
+ {% endif %}
+ </div>
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-white">
+ <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+ <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/>
+ </svg>
+ </div>
+ <div class="absolute z-10 w-full mt-1 bg-neutral-900 rounded shadow-lg hidden max-h-96 overflow-y-scroll no-scrollbar" id="score_options">
+ <div class="py-1">
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="10">10</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="9">9</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="8">8</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="7">7</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="6">6</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="5">5</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="4">4</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="3">3</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="2">2</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="1">1</div>
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="Score">0</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="flex-1 flex flex-col gap-2">
+ <span>Update MAL Episodes</span>
+ <div class="relative w-full custom-select text-sm" data-select="episodes_m">
+ <div class="select-none cursor-pointer bg-neutral-900 py-2 px-4 pr-8 rounded leading-tight focus:outline-none" id="episodes_m">
+ {% if mal_data.my_list_status.num_episodes_watched %}
+ {{ mal_data.my_list_status.num_episodes_watched }}
+ {% else %}
+ Episodes
+ {% endif %}
+ </div>
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-white">
+ <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+ <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/>
+ </svg>
+ </div>
+ <div class="absolute z-10 w-full mt-1 bg-neutral-900 rounded shadow-lg hidden max-h-96 overflow-y-scroll no-scrollbar" id="episodes_m_options">
+ <div class="py-1">
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="Episodes">0</div>
+ {% for i in mal_episode_range %}
+ <div class="cursor-pointer px-4 py-2 text-white hover:bg-{{ user.preferences.accent_colour }}-600" data-value="{{ i }}">{{ i }}</div>
+ {% endfor %}
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ {% endif %}
+
+ <section class="w-full flex flex-col items-center justify-center p-2 relative detail-section" id="dss">
+ <section class="inline-flex w-max flex-row gap-4 rounded-full mb-8 bg-white bg-opacity-10 mx-auto">
+ <button class="flex flex-row items-center focus:outline-none gap-2 text-sm font-bold py-2 px-4 rounded-full category-switch" data-target="characters">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4">
+ <path fill-rule="evenodd" d="M18.685 19.097A9.723 9.723 0 0 0 21.75 12c0-5.385-4.365-9.75-9.75-9.75S2.25 6.615 2.25 12a9.723 9.723 0 0 0 3.065 7.097A9.716 9.716 0 0 0 12 21.75a9.716 9.716 0 0 0 6.685-2.653Zm-12.54-1.285A7.486 7.486 0 0 1 12 15a7.486 7.486 0 0 1 5.855 2.812A8.224 8.224 0 0 1 12 20.25a8.224 8.224 0 0 1-5.855-2.438ZM15.75 9a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z" clip-rule="evenodd" />
+ </svg>
+ <span>Characters</span>
+ </button>
+ <button class="flex flex-row items-center focus:outline-none gap-2 text-sm font-bold py-2 px-4 rounded-full category-switch bg-{{ user.preferences.accent_colour }}-600" data-target="chapters">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4">
+ <path fill-rule="evenodd" d="M1.5 5.625c0-1.036.84-1.875 1.875-1.875h17.25c1.035 0 1.875.84 1.875 1.875v12.75c0 1.035-.84 1.875-1.875 1.875H3.375A1.875 1.875 0 0 1 1.5 18.375V5.625Zm1.5 0v1.5c0 .207.168.375.375.375h1.5a.375.375 0 0 0 .375-.375v-1.5a.375.375 0 0 0-.375-.375h-1.5A.375.375 0 0 0 3 5.625Zm16.125-.375a.375.375 0 0 0-.375.375v1.5c0 .207.168.375.375.375h1.5A.375.375 0 0 0 21 7.125v-1.5a.375.375 0 0 0-.375-.375h-1.5ZM21 9.375A.375.375 0 0 0 20.625 9h-1.5a.375.375 0 0 0-.375.375v1.5c0 .207.168.375.375.375h1.5a.375.375 0 0 0 .375-.375v-1.5Zm0 3.75a.375.375 0 0 0-.375-.375h-1.5a.375.375 0 0 0-.375.375v1.5c0 .207.168.375.375.375h1.5a.375.375 0 0 0 .375-.375v-1.5Zm0 3.75a.375.375 0 0 0-.375-.375h-1.5a.375.375 0 0 0-.375.375v1.5c0 .207.168.375.375.375h1.5a.375.375 0 0 0 .375-.375v-1.5ZM4.875 18.75a.375.375 0 0 0 .375-.375v-1.5a.375.375 0 0 0-.375-.375h-1.5a.375.375 0 0 0-.375.375v1.5c0 .207.168.375.375.375h1.5ZM3.375 15h1.5a.375.375 0 0 0 .375-.375v-1.5a.375.375 0 0 0-.375-.375h-1.5a.375.375 0 0 0-.375.375v1.5c0 .207.168.375.375.375Zm0-3.75h1.5a.375.375 0 0 0 .375-.375v-1.5A.375.375 0 0 0 4.875 9h-1.5A.375.375 0 0 0 3 9.375v1.5c0 .207.168.375.375.375Zm4.125 0a.75.75 0 0 0 0 1.5h9a.75.75 0 0 0 0-1.5h-9Z" clip-rule="evenodd" />
+ </svg>
+ <span>Chapters</span>
+ </button>
+ <button class="flex flex-row items-center focus:outline-none gap-2 text-sm font-bold py-2 px-4 rounded-full category-switch" data-target="trailer">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4">
+ <path d="M4.5 4.5a3 3 0 0 0-3 3v9a3 3 0 0 0 3 3h8.25a3 3 0 0 0 3-3v-9a3 3 0 0 0-3-3H4.5ZM19.94 18.75l-2.69-2.69V7.94l2.69-2.69c.944-.945 2.56-.276 2.56 1.06v11.38c0 1.336-1.616 2.005-2.56 1.06Z" />
+ </svg>
+ <span>Trailer</span>
+ </button>
+ </section>
+ <section id="characters" class="w-full hidden">
+ <div class="flex flex-wrap">
+ {% for character in manga.characters %}
+ <div class="w-full lg:w-1/2 px-4 py-2 flex justify-between">
+ <div class="flex flex-row gap-2 items-center">
+ <img loading="lazy"loading="lazy"src="{{ character.image }}" alt="{{ character.name }}" class="rounded-full w-16 h-16 object-cover"/>
+ <div class="flex flex-col gap-2">
+ <span class="font-bold">
+ {% if user.preferences.character_name_language == "romaji" %}
+ {{ character.name.full }}
+ {% else %}
+ {{ character.name.native }}
+ {% endif %}
+ </span>
+ <span class="capitalize">{{ character.role }}</span>
+ </div>
+ </div>
+ <div class="flex flex-col items-end">
+ {% for voice_actor in character.voiceActors|slice:":1" %}
+ <div class="flex flex-row gap-2 items-center mb-2">
+ <div class="flex flex-col gap-2 text-right">
+ <span class="font-bold">
+ {% if user.preferences.character_name_language == "romaji" %}
+ {{ voice_actor.name.full }}
+ {% else %}
+ {{ voice_actor.name.native }}
+ {% endif %}
+ </span>
+ <span class="capitalize">{{ voice_actor.language }}</span>
+ </div>
+ <img loading="lazy" src="{{ voice_actor.image }}" alt="{{ voice_actor.name }}" class="rounded-full w-16 h-16 object-cover"/>
+ </div>
+ {% endfor %}
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+ </section>
+ <section id="chapters" class="w-full flex-wrap flex justify-start max-h-[540px] overflow-auto">
+ {% for chapter in manga.chapters %}
+ <a href="#" class="w-full px-2 mb-2 flex flex-row gap-4 justify-between items-center bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30 mb-2">
+ {% if chapter.title %}
+ <span class="font-bold">{{ chapter.title }}</span>
+ {% else %}
+ <span class="font-bold">Chapter {{ forloop.counter }}</span>
+ {% endif %}
+ </a>
+ {% endfor %}
+ {% if not manga.chapters %}
+ <div class="w-full h-96 flex flex-col gap-2 items-center justify-center">
+ <p>No Chapters Available</p>
+ </div>
+ {% endif %}
+ </section>
+ <section id="trailer" class="w-full hidden">
+ {% if manga.trailer and manga.trailer.site == "youtube" %}
+ <iframe src="https://www.youtube.com/embed/{{ manga.trailer.id }}" title="{{ manga.title.english }} Trailer" class="w-full aspect-video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" credentialless allowfullscreen></iframe>
+ {% else %}
+ <div class="w-full h-96 flex items-center justify-center">
+ <span>No Trailer Available</span>
+ </div>
+ {% endif %}
+ </section>
+ </section>
+ <div class="w-full w-fix">
+ {% if related %}
+ <div class="text-xl font-bold text-white uppercase flex flex-row items-center gap-1 mb-4">
+ <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 256 512" class="size-4" xmlns="http://www.w3.org/2000/svg"><path d="M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"></path></svg>
+ <span>Related</span>
+ </div>
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-2">
+ {% for related in related|slice:":5" %}
+ {% if related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" or related.type == "MANGA" or related.type == "NOVEL" %}
+ <a {% if related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" %}href="{% url 'detail:anime' related.id %}"{% elif related.type == "MANGA" %}href="{% url 'detail:manga' related.id %}"{% else %}onClick="showToast('{% if related.type == "MANGA" %}Manga{% else %}Novel{% endif %} reading is not supported yet!', false)"{% endif %} class="cursor-pointer flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ <img loading="lazy" src="{{ related.image }}" alt="{{ related.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
+ <div class="flex flex-col gap-2">
+ <span class="font-bold flex gap-2 flex-row items-center">
+ {% if related.status == "Ongoing" %}
+ <span class="text-green-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% elif related.status == "Not yet aired" %}
+ <span class="text-yellow-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% else %}
+ <span class="text-blue-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% endif %}
+ <span>
+ {% if user.preferences.title_language == "english" and related.title.english %}
+ {{ related.title.english }}
+ {% elif user.preferences.title_language == "native" and related.title.native %}
+ {{ related.title.native }}
+ {% else %}
+ {{ related.title.romaji }}
+ {% endif %}
+ </span>
+ </span>
+ <span class="text-xs sm:text-sm font-bold flex gap-1 flex-row items-start">
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" class="mr-1">
+ <path d="M3.604 7.197l7.138 -3.109a.96 .96 0 0 1 1.27 .527l4.924 11.902a1 1 0 0 1 -.514 1.304l-7.137 3.109a.96 .96 0 0 1 -1.271 -.527l-4.924 -11.903a1 1 0 0 1 .514 -1.304z"></path>
+ <path d="M15 4h1a1 1 0 0 1 1 1v3.5"></path>
+ <path d="M20 6c.264 .112 .52 .217 .768 .315a1 1 0 0 1 .53 1.311l-2.298 5.374"></path>
+ </svg>
+ {{ related.type }}
+ </span>
+ {% if related.rating %}
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"/>
+ </svg>
+ {{ related.rating }}
+ </span>
+ {% endif %}
+ {% if related.relationType %}
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4">
+ <path d="m11.645 20.91-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z" />
+ </svg>
+ {{ related.relationType }}
+ </span>
+ {% endif %}
+ {% if related.episodes %}
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M5.25 8.25h15m-16.5 7.5h15m-1.8-13.5-3.9 19.5m-2.1-19.5-3.9 19.5"/>
+ </svg>
+ {{ related.episodes }}
+ </span>
+ {% endif %}
+ </span>
+ </div>
+ </a>
+ {% endif %}
+ {% endfor %}
+ </div>
+ {% endif %}
+ {% if recommendations %}
+ <div class="text-xl font-bold text-white uppercase flex flex-row items-center gap-1 my-4">
+ <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 256 512" class="size-4" xmlns="http://www.w3.org/2000/svg"><path d="M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"></path></svg>
+ <span>Recommendations</span>
+ </div>
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-2">
+ {% for recommendation in recommendations|slice:":10" %}
+ {% if recommendation.id and recommendation.type == "TV" or recommendation.type == "MOVIE" or recommendation.type == "OVA" or recommendation.type == "ONA" or recommendation.type == "SPECIAL" or recommendation.type == "TV_SHORT" or recommendation.type == "MANGA" or recommendation.type == "NOVEL" %}
+ <a href="{% if recommendation.type == "TV" or recommendation.type == "MOVIE" or recommendation.type == "OVA" or recommendation.type == "ONA" or recommendation.type == "SPECIAL" or recommendation.type == "TV_SHORT" %}{% url 'detail:anime' recommendation.id %}{% elif recommendation.type == "MANGA" or recommendation.type == "NOVEL" %}{% url 'detail:manga' recommendation.id %}{% else %}{% url 'detail:manga' recommendation.id %}{% endif %}" class="flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ <img loading="lazy" src="{{ recommendation.image }}" alt="{{ recommendation.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
+ <div class="flex flex-col gap-2 max-w-[calc(100%-4rem)]">
+ <span class="font-bold flex gap-2 flex-row items-center">
+ {% if recommendation.status == "Ongoing" %}
+ <span class="text-green-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% elif recommendation.status == "Not yet aired" %}
+ <span class="text-yellow-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% else %}
+ <span class="text-blue-500">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
+ <circle cx="12" cy="12" r="12" />
+ </svg>
+ </span>
+ {% endif %}
+ <span class="truncate max-w-full overflow-hidden text-ellipsis whitespace-nowrap">
+ {% if user.preferences.title_language == "english" and recommendation.title.english %}
+ {{ recommendation.title.english }}
+ {% elif user.preferences.title_language == "native" and recommendation.title.native %}
+ {{ recommendation.title.native }}
+ {% else %}
+ {{ recommendation.title.romaji }}
+ {% endif %}
+ </span>
+ </span>
+ <span class="text-xs sm:text-sm font-bold flex gap-1 flex-row items-start">
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" class="mr-1">
+ <path d="M3.604 7.197l7.138 -3.109a.96 .96 0 0 1 1.27 .527l4.924 11.902a1 1 0 0 1 -.514 1.304l-7.137 3.109a.96 .96 0 0 1 -1.271 -.527l-4.924 -11.903a1 1 0 0 1 .514 -1.304z"></path>
+ <path d="M15 4h1a1 1 0 0 1 1 1v3.5"></path>
+ <path d="M20 6c.264 .112 .52 .217 .768 .315a1 1 0 0 1 .53 1.311l-2.298 5.374"></path>
+ </svg>
+ {{ recommendation.type }}
+ </span>
+ {% if recommendation.rating %}
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a
+ .563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"/>
+ </svg>
+ {{ recommendation.rating }}
+ </span>
+ {% if recommendation.episodes %}
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M5.25 8.25h15m-16.5 7.5h15m-1.8-13.5-3.9 19.5m-2.1-19.5-3.9 19.5"/>
+ </svg>
+ {{ recommendation.episodes }}
+ </span>
+ {% endif %}
+ {% if recommendation.chapters %}
+ <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
+ <path stroke-linecap="round" stroke-linejoin="round" d="M5.25 8.25h15m-16.5 7.5h15m-1.8-13.5-3.9 19.5m-2.1-19.5-3.9 19.5"/>
+ </svg>
+ {{ recommendation.chapters }}
+ </span>
+ {% endif %}
+ </span>
+ {% endif %}
+ </div>
+ </a>
+ {% endif %}
+ {% endfor %}
+ </div>
+ {% endif %}
+ </div>
+ </div>
+</div>
+<div id="toastContainer" class="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-50 flex flex-col space-y-2"></div>
+{% endblock content %}
+{% block scripts %}
+<script>
+ const categorySwitch = document.querySelectorAll(".category-switch");
+ categorySwitch.forEach((button) => {
+ button.addEventListener("click", () => {
+ categorySwitch.forEach((button) => {
+ button.classList.remove("active-category");
+ button.classList.remove("bg-{{ user.preferences.accent_colour }}-600");
+ });
+ button.classList.add("active-category");
+ button.classList.add("bg-{{ user.preferences.accent_colour }}-600");
+
+ const target = button.getAttribute("data-target");
+ const sections = [document.getElementById("characters"), document.getElementById("chapters"), document.getElementById("trailer")];
+ sections.forEach((section) => {
+ section.classList.add("hidden");
+ section.classList.remove("flex");
+ });
+ document.getElementById(target).classList.remove("hidden");
+ document.getElementById(target).classList.add("flex");
+ });
+ });
+
+ function showToast(message, isSuccess) {
+ const toast = document.createElement('div');
+ toast.className = `flex items-center p-4 rounded-md shadow-lg transition-opacity duration-500 ease-in-out animate__animated ${
+ isSuccess ? 'bg-green-100 text-green-700 animate__fadeInUp' : 'bg-red-100 text-red-700 animate__fadeInUp'
+ }`;
+
+ const checkSVG = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" /></svg>`
+
+ const errorSVG = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /></svg>`
+
+ toast.innerHTML = `
+ <div class="flex items-center">
+ ${isSuccess ? checkSVG : errorSVG}
+ <span class="ml-2">${message}</span>
+ </div>
+ `;
+
+ // Append the toast to the container
+ toastContainer.appendChild(toast);
+
+ // Remove the toast after 3 seconds
+ setTimeout(() => {
+ toast.classList.add('animate__fadeOutDown');
+ setTimeout(() => {
+ toastContainer.removeChild(toast);
+ }, 500);
+ }, 3000);
+ }
+
+ {% if mal_data %}
+ const customSelects = document.querySelectorAll('.custom-select')
+ customSelects.forEach(customSelect => {
+ const selectId = customSelect.getAttribute('data-select')
+ const customSelectDisplay = document.getElementById(selectId)
+ const customSelectOptions = document.getElementById(`${selectId}_options`)
+ let selectedValue = '';
+
+ customSelectDisplay.addEventListener('click', function() {
+ customSelectOptions.classList.toggle('hidden');
+ });
+
+ customSelectOptions.addEventListener('click', function(e) {
+ if (e.target.hasAttribute('data-value')) {
+ selectedValue = e.target.getAttribute('data-value');
+ customSelectDisplay.textContent = selectedValue;
+ customSelectOptions.classList.add('hidden');
+ }
+ });
+
+ // Close the dropdown when clicking outside
+ document.addEventListener('click', function(e) {
+ if (!customSelectDisplay.contains(e.target) && !customSelectOptions.contains(e.target)) {
+ customSelectOptions.classList.add('hidden');
+ }
+ });
+ });
+
+ const statusSelect = document.getElementById('status');
+ const scoreSelect = document.getElementById('score');
+ const episodesSelect = document.getElementById('episodes_m');
+
+ // Call the API to update the user's list
+ const observer = new MutationObserver(function(mutations){
+ mutations.forEach(function(mutation){
+ if (mutation.type === 'characterData' || mutation.type === 'childList') {
+ const statusSelectedOption = statusSelect.textContent.trim().toLowerCase().replace(/\s/g, '_');
+ const scoreSelectedOption = scoreSelect.textContent.trim();
+ const episodesSelectedOption = episodesSelect.textContent.trim();
+
+ const data = {
+ 'status': statusSelectedOption === 'Add to List' ? 'add_to_list' : statusSelectedOption,
+ 'score': scoreSelectedOption === 'Score' ? 0 : parseInt(scoreSelectedOption),
+ 'episodes': episodesSelectedOption === 'Episodes' ? 0 : parseInt(episodesSelectedOption),
+ 'mal_id': {{ mal_data.id }},
+ };
+
+ fetch('{% url "user_profile:update_user_mal_list" %}', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-CSRFToken': '{{ csrf_token }}',
+ },
+ body: JSON.stringify(data),
+ }).then(response => {
+ if (response.ok) {
+ return response.json();
+ } else {
+ return response.json().then(data => {
+ throw new Error(data.error);
+ });
+ }
+ }).then(data => {
+ showToast(data.success, true);
+ }).catch(error => {
+ showToast(error, false);
+ });
+ }
+ });
+ });
+
+ observer.observe(statusSelect, {childList: true, characterData: true});
+ observer.observe(scoreSelect, {childList: true, characterData: true});
+ observer.observe(episodesSelect, {childList: true, characterData: true});
+ {% endif %}
+</script>
+{% endblock scripts %} \ No newline at end of file
diff --git a/templates/partials/mangacard_render.html b/templates/partials/mangacard_render.html
index a62ff3e..04607e4 100644
--- a/templates/partials/mangacard_render.html
+++ b/templates/partials/mangacard_render.html
@@ -1,6 +1,6 @@
{% for manga in data %}
<div class="w-1/2 md:w-1/3 lg:w-1/4 xl:w-1/6 text-gray-500 p-1 sm:p-2 mb-4 hover:text-white flex flex-col">
- <a href="{{ manga.id }}">
+ <a href="{% url "detail:manga" manga.id %}">
<div class="relative pt-[140%]">
<img loading="lazy" src="{{ manga.coverImage.large }}" alt="{{ manga.title.english }}" class="absolute top-0 left-0 w-full h-full rounded-lg object-cover"/>
</div>
diff --git a/templates/partials/mangacardcompact_render.html b/templates/partials/mangacardcompact_render.html
index 5ded96c..96858ca 100644
--- a/templates/partials/mangacardcompact_render.html
+++ b/templates/partials/mangacardcompact_render.html
@@ -1,6 +1,6 @@
{% for manga in data %}
<div class="w-full max-w-full px-2 mb-2">
- <a href="#">
+ <a href="{% url "detail:manga" manga.id %}">
<div class="flex flex-row bg-neutral-950 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30 p-2 gap-4 items-center">
<img loading="lazy" src="{{ manga.coverImage.large }}" alt="{{ manga.title.english }}" class="rounded-lg w-16 lg:w-12 h-24 lg:h-16 object-cover"/>
<div class="flex flex-col lg:flex-row gap-2 max-w-[calc(100%-6rem)] lg:items-center">
diff --git a/templates/partials/mangacardwide_render.html b/templates/partials/mangacardwide_render.html
index 4c7208f..d27db8c 100644
--- a/templates/partials/mangacardwide_render.html
+++ b/templates/partials/mangacardwide_render.html
@@ -3,7 +3,7 @@
<div class="w-full lg:w-1/2 px-2 mb-2">
<div class="flex flex-row w-full bg-neutral-950 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30 p-2 gap-4">
<div class="flex flex-col gap-2 min-w-32">
- <a href="#"><img loading="lazy" src="{{ manga.coverImage.large }}" alt="{{ manga.title.english }}" class="rounded-lg w-32 h-48 object-cover"/></a>
+ <a href="{% url "detail:manga" manga.id %}"><img loading="lazy" src="{{ manga.coverImage.large }}" alt="{{ manga.title.english }}" class="rounded-lg w-32 h-48 object-cover"/></a>
<div class="flex flex-row gap-2">
<a href="https://anilist.co/manga/{{ manga.id }}" target="_blank" class="text-xs font-bold bg-white bg-opacity-10 hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30 rounded px-2 py-1">
<svg stroke="currentColor" fill="currentColor" stroke-width="0" role="img" viewBox="0 0 24 24" height="1.5rem" width="1.5rem" xmlns="http://www.w3.org/2000/svg"><path d="M24 17.53v2.421c0 .71-.391 1.101-1.1 1.101h-5l-.057-.165L11.84 3.736c.106-.502.46-.788 1.053-.788h2.422c.71 0 1.1.391 1.1 1.1v12.38H22.9c.71 0 1.1.392 1.1 1.101zM11.034 2.947l6.337 18.104h-4.918l-1.052-3.131H6.019l-1.077 3.131H0L6.361 2.948h4.673zm-.66 10.96-1.69-5.014-1.541 5.015h3.23z"></path></svg>
@@ -13,7 +13,7 @@
</a>
</div>
</div>
- <a href="#" class="flex flex-col gap-2 w-full justify-around max-w-[calc(100%-10rem)]">
+ <a href="{% url "detail:manga" manga.id %}" class="flex flex-col gap-2 w-full justify-around max-w-[calc(100%-10rem)]">
<h2 class="text-xl font-bold text-transparent bg-clip-text block w-full truncate overflow-hidden text-ellipsis whitespace-nowrap" style="background: linear-gradient(-45deg, {% if manga.color %}{{ manga.color }}{% else %}white{% endif %}, white); -webkit-background-clip: text; background-clip: text;">
{% if user.preferences.title_language == "english" and manga.title.english %}
{{ manga.title.english }}
diff --git a/templates/watch/watch.html b/templates/watch/watch.html
index 04a7007..58765ae 100644
--- a/templates/watch/watch.html
+++ b/templates/watch/watch.html
@@ -676,69 +676,8 @@
</div>
<div class="flex flex-col gap-2">
{% for related in related|slice:":5" %}
- {% if related.type == "MANGA" or related.type == "NOVEL" %}
- <div onClick="showToast('{% if related.type == "MANGA" %}Manga{% else %}Novel{% endif %} reading is not supported yet!', false)" class="cursor-pointer flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
- <img loading="lazy"src=" {{ related.image }}" alt="{{ related.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
- <div class="flex flex-col gap-2">
- <span class="font-bold flex gap-2 flex-row items-center">
- {% if related.status == "Ongoing" %}
- <span class="text-green-500">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
- <circle cx="12" cy="12" r="12" />
- </svg>
- </span>
- {% elif related.status == "Not yet aired" %}
- <span class="text-yellow-500">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
- <circle cx="12" cy="12" r="12" />
- </svg>
- </span>
- {% else %}
- <span class="text-blue-500">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-2 sm:size-3">
- <circle cx="12" cy="12" r="12" />
- </svg>
- </span>
- {% endif %}
- <span>
- {% if user.preferences.title_language == "english" and related.title.english %}
- {{ related.title.english }}
- {% elif user.preferences.title_language == "native" and related.title.native %}
- {{ related.title.native }}
- {% else %}
- {{ related.title.romaji }}
- {% endif %}
- </span>
- </span>
- <span class="text-xs sm:text-sm font-bold flex gap-1 flex-row items-start">
- <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
- <svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" class="mr-1">
- <path d="M3.604 7.197l7.138 -3.109a.96 .96 0 0 1 1.27 .527l4.924 11.902a1 1 0 0 1 -.514 1.304l-7.137 3.109a.96 .96 0 0 1 -1.271 -.527l-4.924 -11.903a1 1 0 0 1 .514 -1.304z"></path>
- <path d="M15 4h1a1 1 0 0 1 1 1v3.5"></path>
- <path d="M20 6c.264 .112 .52 .217 .768 .315a1 1 0 0 1 .53 1.311l-2.298 5.374"></path>
- </svg>
- {{ related.type }}
- </span>
- <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-4">
- <path d="m11.645 20.91-.007-.003-.022-.012a15.247 15.247 0 0 1-.383-.218 25.18 25.18 0 0 1-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0 1 12 5.052 5.5 5.5 0 0 1 16.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 0 1-4.244 3.17 15.247 15.247 0 0 1-.383.219l-.022.012-.007.004-.003.001a.752.752 0 0 1-.704 0l-.003-.001Z" />
- </svg>
- {{ related.relationType }}
- </span>
- {% if related.rating %}
- <span class="text-xs font-bold bg-white bg-opacity-10 p-1 rounded flex items-center gap-1">
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
- <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 0 1 1.04 0l2.125 5.111a.563.563 0 0 0 .475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 0 0-.182.557l1.285 5.385a.562.562 0 0 1-.84.61l-4.725-2.885a.562.562 0 0 0-.586 0L6.982 20.54a.562.562 0 0 1-.84-.61l1.285-5.386a.562.562 0 0 0-.182-.557l-4.204-3.602a.562.562 0 0 1 .321-.988l5.518-.442a.563.563 0 0 0 .475-.345L11.48 3.5Z"/>
- </svg>
- {{ related.rating }}
- </span>
- {% endif %}
- </span>
- </div>
- </div>
- {% endif %}
- {% if related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" %}
- <a href="{% url 'watch:watch' related.id %}" class="flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ {% if related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" or related.type == "MANGA" or related.type == "NOVEL" %}
+ <a {% if related.type == "TV" or related.type == "MOVIE" or related.type == "OVA" or related.type == "ONA" or related.type == "SPECIAL" or related.type == "TV_SHORT" %}href="{% url 'detail:anime' related.id %}"{% elif related.type == "MANGA" %}href="{% url 'detail:manga' related.id %}"{% else %}onClick="showToast('{% if related.type == "MANGA" %}Manga{% else %}Novel{% endif %} reading is not supported yet!', false)"{% endif %} class="cursor-pointer flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
<img loading="lazy" src="{{ related.image }}" alt="{{ related.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
<div class="flex flex-col gap-2">
<span class="font-bold flex gap-2 flex-row items-center">
@@ -818,8 +757,8 @@
</div>
<div class="flex flex-col gap-2">
{% for recommendation in recommendations|slice:":10" %}
- {% if recommendation.id or recommendation.zid %}
- <a href="{% url 'watch:watch' recommendation.id %}" class="flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ {% if recommendation.id and recommendation.type == "TV" or recommendation.type == "MOVIE" or recommendation.type == "OVA" or recommendation.type == "ONA" or recommendation.type == "SPECIAL" or recommendation.type == "TV_SHORT" or recommendation.type == "MANGA" or recommendation.type == "NOVEL" %}
+ <a {% if recommendation.type == "TV" or recommendation.type == "MOVIE" or recommendation.type == "OVA" or recommendation.type == "ONA" or recommendation.type == "SPECIAL" or recommendation.type == "TV_SHORT" %}href="{% url 'detail:anime' recommendation.id %}"{% elif recommendation.type == "MANGA" %}href="{% url 'detail:manga' recommendation.id %}"{% else %}onClick="showToast('{% if related.type == "MANGA" %}Manga{% else %}Novel{% endif %} reading is not supported yet!', false)"{% endif %} class="flex flex-row w-full gap-4 bg-white bg-opacity-10 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
<img loading="lazy" src="{{ recommendation.image }}" alt="{{ recommendation.title.english }}" class="rounded-lg w-12 h-16 object-cover"/>
<div class="flex flex-col gap-2 max-w-[calc(100%-4rem)]">
<span class="font-bold flex gap-2 flex-row items-center">