..
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 %}
|
|