skip queue
This commit is contained in:
@@ -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 |
@@ -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 {
|
||||||
|
|||||||
@@ -41,14 +41,19 @@ Stemmen
|
|||||||
></a>
|
></a>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<div class="skip-wrapper">
|
||||||
|
{% 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 }}"}' >
|
||||||
{% if undo %}
|
{% if undo %}
|
||||||
<!--<form class="undo-wrapper" method="post" action="{% url 'undo' %}" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' >-->
|
|
||||||
<div class="undo-wrapper" hx-vals='{"spotify_id": "{{ undo.track.id }}"}' >
|
|
||||||
{% 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 %}
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
|
|||||||
+27
-4
@@ -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:
|
||||||
raise Exception(f"{request.user} already voted for {track}")
|
if not prevote.skipped:
|
||||||
|
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()
|
||||||
|
|||||||
Reference in New Issue
Block a user