skip queue

This commit is contained in:
2024-07-20 09:52:50 +02:00
parent 5858cee900
commit 58e8bbbbef
7 changed files with 59 additions and 10 deletions
+1
View File
@@ -7,3 +7,4 @@ class Vote(models.Model):
track = models.ForeignKey('Track', on_delete=models.CASCADE) track = models.ForeignKey('Track', on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
points = models.IntegerField() points = models.IntegerField()
skipped = models.BooleanField(default=False)
Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

+12
View File
@@ -457,6 +457,7 @@ input[type="range"]#volume::-webkit-slider-thumb {
.undo-wrapper p { .undo-wrapper p {
flex-grow: 1; flex-grow: 1;
padding: 0 5px; padding: 0 5px;
text-align: right;
} }
.undo { .undo {
@@ -465,6 +466,17 @@ input[type="range"]#volume::-webkit-slider-thumb {
background-position: 50% 0; background-position: 50% 0;
padding: 32px 0 4px 0; padding: 32px 0 4px 0;
height: 50px; height: 50px;
min-width: 40px;
}
.skip {
background-image: url(img/download.png);
background-repeat: no-repeat;
background-position: 50% 20%;
padding: 32px 0 4px 0;
height: 50px;
min-width: 40px;
margin-left: 5px;
} }
.progress-indicator { .progress-indicator {
+8 -3
View File
@@ -41,16 +41,21 @@ Stemmen
></a> ></a>
</div> </div>
</fieldset> </fieldset>
{% if undo %} <div class="skip-wrapper">
<!--<form class="undo-wrapper" method="post" action="{% url 'undo' %}" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' >--> {% if not skipped %}
{% csrf_token %}
<button class="skip" hx-post="{% url 'skip' %}" >Skip</button>
{% endif %}
</div>
<div class="undo-wrapper" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' > <div class="undo-wrapper" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' >
{% if undo %}
{% csrf_token %} {% csrf_token %}
<p>Je hebt {{undo.track}} een score van {{undo.points}} sterren gegeven!</p> <p>Je hebt {{undo.track}} een score van {{undo.points}} sterren gegeven!</p>
<button class="undo" hx-post="{% url 'undo' %}" >Undo</button> <button class="undo" hx-post="{% url 'undo' %}" >Undo</button>
</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div>
{% else %} {% else %}
<p hx-boost="true"> <p hx-boost="true">
Je hebt niets meer om te stemmen. Lekker bezig! Je hebt niets meer om te stemmen. Lekker bezig!
+1
View File
@@ -7,6 +7,7 @@ urlpatterns = [
path('track/', views.NominateView.as_view(), name="nominate"), path('track/', views.NominateView.as_view(), name="nominate"),
path('vote/', views.VoteView.as_view(), name="vote"), path('vote/', views.VoteView.as_view(), name="vote"),
path('vote/undo', views.UndoView.as_view(), name="undo"), path('vote/undo', views.UndoView.as_view(), name="undo"),
path('vote/skip', views.SkipView.as_view(), name="skip"),
path('settings/', views.SettingsView.as_view(), name="settings"), path('settings/', views.SettingsView.as_view(), name="settings"),
path('overview/', views.OverView.as_view(), name="overview"), path('overview/', views.OverView.as_view(), name="overview"),
path('overview/playlist', views.PlaylistListView.as_view(), name="playlist-list"), path('overview/playlist', views.PlaylistListView.as_view(), name="playlist-list"),
+10 -3
View File
@@ -10,11 +10,18 @@ def from_json(cls, json):
return cls.objects.create(**subset) return cls.objects.create(**subset)
def get_unvoted(user): def get_unvoted(user):
"""Gets next voting track for user. Returns a pair with track and flag if this was a skipped track"""
votes = set(Vote.objects.filter(user=user).values_list('track_id', flat=True)) votes = set(Vote.objects.filter(user=user).values_list('track_id', flat=True))
tracks = set(Track.objects.filter(banter_done=True).values_list('pk', flat=True)) tracks = set(Track.objects.filter(banter_done=True).values_list('pk', flat=True))
seed(user.username) seed(user.username)
try: try:
random_track = choice(list(tracks - votes)) queue = list(tracks - votes)
return Track.objects.get(pk=random_track) skipped = False
if not queue:
skipped = True
queue = list(Vote.objects.filter(user=user).filter(skipped=True).values_list('track_id', flat=True))
random_track = choice(queue)
choice
return (Track.objects.get(pk=random_track), skipped)
except IndexError: except IndexError:
return None return (None, False)
+26 -3
View File
@@ -26,10 +26,10 @@ class AuthView(View):
class VoteView(LoginRequiredMixin, View): class VoteView(LoginRequiredMixin, View):
def get(self, request, undo=None): def get(self, request, undo=None):
track = get_unvoted(request.user) (track, skipped) = get_unvoted(request.user)
if track and not track.album.image: if track and not track.album.image:
get_and_dither_image(track.album.image_url, track.album, "image") get_and_dither_image(track.album.image_url, track.album, "image")
return TemplateResponse(request, "Vote.html", {"track": track, "undo": undo}) return TemplateResponse(request, "Vote.html", {"track": track, "undo": undo, "skipped": skipped})
def post(self, request): def post(self, request):
(profile,_) = Profile.objects.get_or_create(user=request.user) (profile,_) = Profile.objects.get_or_create(user=request.user)
try: try:
@@ -40,11 +40,14 @@ class VoteView(LoginRequiredMixin, View):
score = min(max(1, score), 5) score = min(max(1, score), 5)
track = Track.objects.get(pk=spotify_id) track = Track.objects.get(pk=spotify_id)
try: try:
Vote.objects.get(user=request.user, track=track) prevote = Vote.objects.get(user=request.user, track=track)
except Vote.DoesNotExist: except Vote.DoesNotExist:
pass pass
else: else:
if not prevote.skipped:
raise Exception(f"{request.user} already voted for {track}") raise Exception(f"{request.user} already voted for {track}")
else:
prevote.delete()
vote = Vote.objects.create(track=track, user=request.user, points=score) vote = Vote.objects.create(track=track, user=request.user, points=score)
(profile,_) = Profile.objects.get_or_create(user=request.user) (profile,_) = Profile.objects.get_or_create(user=request.user)
profile.last_voted = track profile.last_voted = track
@@ -186,6 +189,26 @@ class UndoView(LoginRequiredMixin, View):
vote.delete() vote.delete()
return HttpResponseRedirect('/vote/') return HttpResponseRedirect('/vote/')
class SkipView(LoginRequiredMixin, View):
def get(self, request):
return HttpResponseRedirect('/vote/')
def post(self, request):
spotify_id = self.request.POST['spotify_id']
track = Track.objects.get(pk=spotify_id)
(profile,_) = Profile.objects.get_or_create(user=request.user)
if not profile.can_vote:
raise Exception(f"{request.user} tried to vote after closing for {track}")
vote = None
try:
vote = Vote.objects.get(user=request.user, track=track)
except Vote.DoesNotExist:
pass
profile.last_voted = None
profile.save()
vote = Vote.objects.create(track=track, user=request.user, points=0, skipped=True)
profile.save()
return self.get(request)
class OverView(LoginRequiredMixin, View): class OverView(LoginRequiredMixin, View):
def get(self, request): def get(self, request):
votes = Vote.objects.select_related().distinct() votes = Vote.objects.select_related().distinct()