Browse Source

finish update loop

subDesTagesMitExtraKaese 2 years ago
parent
commit
b454e05353

+ 2 - 2
locale/de/LC_MESSAGES/django.po

@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-12-18 01:25+0000\n"
+"POT-Creation-Date: 2022-12-18 13:06+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -28,7 +28,7 @@ msgstr ""
 msgid "Event not found"
 msgstr ""
 
-#: zitap/templates/zitap/event.html:45
+#: zitap/templates/zitap/event.html:38
 msgid "Logout"
 msgstr ""
 

+ 7 - 2
zitap/helpers.py

@@ -28,7 +28,9 @@ def get_slot_count( event ) -> int :
     # Get the timespan of the event
     start_time = datetime.datetime.combine(datetime.date.today(), event.start_time)
     end_time = datetime.datetime.combine(datetime.date.today(), event.end_time)
-    timespan = abs(end_time - start_time)
+    if(start_time>end_time):
+        end_time += datetime.timedelta(days=1)
+    timespan = end_time - start_time
 
     # Get the number of slots in the event
     days = event.date_set.count()
@@ -50,7 +52,9 @@ def slots2grid( event : Event, participants : list[Participant]) -> dict :
     # Get the timespan of the event
     start_time = datetime.datetime.combine(datetime.date.today(), event.start_time)
     end_time = datetime.datetime.combine(datetime.date.today(), event.end_time)
-    timespan = abs(end_time - start_time)
+    if(start_time>end_time):
+        end_time += datetime.timedelta(days=1)
+    timespan = end_time - start_time
     
     # Get the slots in a day
     slots_per_day = int(timespan.total_seconds() // event.slot_interval.total_seconds())
@@ -80,6 +84,7 @@ def slots2grid( event : Event, participants : list[Participant]) -> dict :
                 'date': date.date,
                 'time': current_time,
                 'color': len(ps),
+                'checked': 'checked="checked"' if len(ps) > 0 else '',
                 'is_full_hour': current_time.hour != last_hour,
                 'is_half_hour': current_time.minute // 30 != last_half_hour,
             })

+ 2 - 1
zitap/static/zitap/css/event.css

@@ -34,7 +34,7 @@
   z-index: 1;
 }
 .occupancy-grid .slot {
-  transition: background-color .2s ease;
+  transition: background-color 1s ease;
   position: relative;
   width: var(--slot-witdh);
   flex-grow: 1;
@@ -61,5 +61,6 @@
 }
 .occupancy-grid .slot:hover {
   background-color: rgb(214, 93, 93) !important;
+  transition: background-color 0.2s ease !important;
   cursor: pointer;
 }

+ 32 - 15
zitap/static/zitap/js/live-updates.js

@@ -12,22 +12,39 @@ window.addEventListener("load", function()
   function updateSlots()
   {
     setTimeout(updateSlots, 5000)
-    fetch(endpoint).then(response => response.json()).then(data => {
-      let maxParticipants = 0
-      for(let i=0; i<gridSlots.length; i++)
+    fetch(endpoint).then(response => response.json()).then(setCheckboxes)
+  }
+
+  function setCheckboxes(data)
+  {
+    let maxParticipants = 0
+    for(let i=0; i<gridSlots.length; i++)
+    {
+      const slot = document.getElementById(`grid_slot_${i}`)
+      let participants = []
+      for(let participant in data)
       {
-        const slot = document.getElementById(`grid_slot_${i}`)
-        let participants = []
-        for(let participant in data)
-        {
-          if(data[participant][i] == '1')
-            participants.push(participant)
-        }
-        slot.style.setProperty("--color-index", participants.length)
-        slot.title = `${slot.title.split('\n')[0]}\n${participants.join(", ")}`
-        maxParticipants = Math.max(participants.length, maxParticipants)
+        if(data[participant][i] == '1')
+          participants.push(participant)
       }
-      occupancyGrid.style.setProperty("--color-count", maxParticipants)
-    })
+      slot.style.setProperty("--color-index", participants.length)
+      slot.title = `${slot.title.split('\n')[0]}\n${participants.join(", ")}`
+      maxParticipants = Math.max(participants.length, maxParticipants)
+    }
+    occupancyGrid.style.setProperty("--color-count", maxParticipants)
   }
+
+  onCheckedChanged = function(checkables) {
+    const data = new URLSearchParams();
+    for (const pair of new FormData(document.getElementById("update-form"))) {
+        data.append(pair[0], pair[1]);
+    }
+
+    fetch(endpoint, {
+        method: 'post',
+        body: data,
+    }).then(response => response.json()).then(setCheckboxes)
+  }
+
+  this.document.getElementById("update-button").style.display = "none"
 })

+ 6 - 0
zitap/static/zitap/js/mouse-drag.js

@@ -1,3 +1,5 @@
+let onCheckedChanged = null
+
 window.addEventListener("load", function()
 {
   let dragStart = null
@@ -44,6 +46,10 @@ window.addEventListener("load", function()
     let rectElement = document.getElementById("rect")
     if (rectElement)
       rectElement.parentNode.removeChild(rectElement)
+
+    if(onCheckedChanged) {
+      onCheckedChanged(checkables)
+    }
   }
   function mouseMoveHandler(e)
   {

+ 1 - 1
zitap/templates/widgets/slot-picker.html

@@ -5,7 +5,7 @@
       {% for slot in day.slots %}
       <div class="slot {% if slot.is_full_hour %} full-hour{% elif slot.is_half_hour %} half-hour{% endif %}" title="{{ slot.tooltip }}">
           {% if slot.is_full_hour %}<div class="time-label">{{ slot.time|date:"H:i" }}</div>{% endif %}
-          <input class="checkable" type="checkbox" id="slot_picker_{{ slot.offset }}" name="slot_{{ slot.offset }}" />
+          <input class="checkable" type="checkbox" id="slot_picker_{{ slot.offset }}" name="slot_{{ slot.offset }}" {{ slot.checked }} />
           <label class="checkable" for="slot_picker_{{ slot.offset }}"></label>
       </div>
       {% endfor %}

+ 4 - 4
zitap/templates/zitap/event.html

@@ -27,24 +27,24 @@
 
 
 {% if update_form %}
-    <form action="{% url 'update-slots' url=event.url %}" method="post">
+    <form action="{% url 'update-slots' url=event.url %}" method="post" id="update-form">
         {% csrf_token %}
         <table>
             {{ update_form.as_table }}
         </table>
-        <input type="submit" value="Update Slots">
+        <input type="submit" value="Update Slots" id="update-button">
     </form>
     <button class="logout" onclick="location.href='{% url 'logout' url=event.url %}'">
         {% trans "Logout" %}
     </button>
     <script type="text/javascript" src="{% static 'zitap/js/mouse-drag.js' %}"></script>
     {% else %}
-    <form action="{% url 'login' url=event.url %}" method="post">
+    <form action="{% url 'login' url=event.url %}" method="post" id="login-form">
         {% csrf_token %}
         <table>
             {{ login_form.as_table }}
         </table>
-        <input type="submit" value="Login to Update Slots">
+        <input type="submit" value="Login to Update Slots" id="login-button">
     </form>
     {% endif %}
     <script type="text/javascript" src="{% static 'zitap/js/live-updates.js' %}"></script>

+ 3 - 3
zitap/views.py

@@ -1,9 +1,9 @@
-import random
 import datetime
 from django.db import IntegrityError
 from django.http import HttpResponseNotFound, HttpResponseRedirect, JsonResponse, HttpResponseNotAllowed
 from django.shortcuts import render
 from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
+from django.views.decorators.csrf import csrf_exempt
 from django.contrib.auth.models import User
 
 from .forms import CreateEventForm, LoginForm, UpdateSlotsForm
@@ -88,7 +88,6 @@ def login(request, url):
 
         auth_login(request, user)
         participant, created = Participant.objects.get_or_create(event=event, user=user)
-        participant.slots = random.getrandbits(get_slot_count(event)).to_bytes((get_slot_count(event)+7) // 8, 'big')
         participant.save()
         request.session['user_id'] = user.id
         return HttpResponseRedirect(f'/{event.url}')
@@ -120,6 +119,7 @@ def update_slots(request, url):
         participant.save()
         return HttpResponseRedirect(f'/{event.url}')
 
+@csrf_exempt
 def slots_api(request, url):
     """
     REST JSON API for slots of all participants of an event
@@ -136,6 +136,7 @@ def slots_api(request, url):
             form = UpdateSlotsForm(request.POST, participant=participant)
             if form.is_valid():
                 data = form.cleaned_data
+                print(data['slots'])
                 participant.slots = string2slots(data['slots'], slot_count)
                 participant.save()
 
@@ -144,7 +145,6 @@ def slots_api(request, url):
         participants = event.participant_set.all()
         for participant in participants:
             data[participant.user.username] = slots2string(participant, slot_count)
-            data[participant.user.username] = ''.join([random.choice(('0', '1')) for _ in range(slot_count)])
         
         return JsonResponse(data)
 

+ 10 - 7
zitap/widgets.py

@@ -1,4 +1,5 @@
 import datetime
+import ctypes
 
 from django.forms.widgets import Widget
 from .models import Participant, Date, Event
@@ -75,17 +76,19 @@ class SlotPickerWidget(Widget):
         return context
 
     def value_from_datadict(self, data, files, name):
-        slots = []
+        # create a mutable string buffer
+        slots = ctypes.create_string_buffer(self.n_slots)
+        # set the slots
         for i in range(self.n_slots):
             if data.get(f"slot_{i}") == "on":
-                slots.append(i)
-        return slots
+                slots[i] = b'1'
+            else:
+                slots[i] = b'0'
+        # return the slots as a string
+        return slots.value
 
     def value_omitted_from_data(self, data, files, name):
-        return not any(
-            (data.get(f"slot_{i}") == "on")
-            for i in range(self.n_slots)
-        )
+        return False
     
     def __init__(self, *args, participant, **kwargs):
         super().__init__(*args, **kwargs)