Socialify

Folder ..

Viewing watchlist.html
95 lines (88 loc) • 5.5 KB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{% extends "partials/base.html" %}
{% block css %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
{% endblock css %}
{% block content %}
<h1 class="text-2xl font-bold mt-4">Currently Watching</h1>
<section class="flex flex-col lg:flex-row flex-wrap my-4 gap-4 justify-center items-start">
    {% for history in watchlist %}
    <a href="{% url "watch:watch_episode" history.anime history.episode %}" class="group rounded-lg aspect-video h-48 relative flex-shrink-0 overflow-hidden">
        <div class="absolute inset-0 bg-center bg-cover transition-transform group-hover:scale-110" style="background-image: url('{{ history.anime_cover_image }}')"></div>
        <div class="absolute inset-0 bg-{{ user.preferences.accent_colour }}-600 opacity-0 group-hover:opacity-30 transition-opacity"></div>
        <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="flex flex-col justify-end h-full p-2 relative z-10">
            <button class="absolute top-2 right-2 bg-white p-1 rounded-full text-gray-700 hover:text-red-600 focus:outline-none" onclick="event.preventDefault(); removeAnime({{ history.anime }});">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
                    <path fill-rule="evenodd" d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z" clip-rule="evenodd" />
                </svg>
            </button>
            <h1 class="text-xl font-bold truncate max-w-full overflow-hidden text-ellipsis whitespace-nowrap">
                {% if user.preferences.title_language == "english" and history.anime_title_english %}
                {{ history.anime_title_english }}
                {% elif user.preferences.title_language == "native" and history.anime_title_native %}
                {{ history.anime_title_native }}
                {% else %}
                {{ history.anime_title_romaji }}
                {% endif %}
            </h1>
            <h2 class="font-bold truncate max-w-full overflow-hidden text-ellipsis whitespace-nowrap">{{ history.episode_title }}</h2>
            <p>Episode {{ history.episode }}</p>
        </div>
    </a>
    {% endfor %}
</section>
<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>
    document.addEventListener('DOMContentLoaded', () => {
        const toastMessage = sessionStorage.getItem('toastMessage');
        if (toastMessage) {
            showToast(toastMessage, true);
            sessionStorage.removeItem('toastMessage');
        }
    });

    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);
    }

    function removeAnime(animeId) {
        fetch("{% url "watch:remove_anime_from_watchlist" %}", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "X-CSRFToken": "{{ csrf_token }}"
            },
            body: JSON.stringify({
                "anime_id": animeId
            })
        }).then(response => {
            if (response.ok) {
                sessionStorage.setItem('toastMessage', 'Anime removed from watchlist');
                location.reload();
            } else {
                showToast('Failed to remove anime from watchlist', false);
            }
        });
    }
</script>
{% endblock scripts %}