diff --git a/src/program/static/js/event_instance_websocket.js b/src/program/static/js/event_instance_websocket.js new file mode 100644 index 00000000..27af8fe9 --- /dev/null +++ b/src/program/static/js/event_instance_websocket.js @@ -0,0 +1,99 @@ +const webSocketBridge = new channels.WebSocketBridge(); +var modals = {}; + +function toggleFavoriteButton(button) { + if(button.getAttribute('data-state') == 'true') { + favorite_button.classList.remove('btn-success'); + favorite_button.classList.add('btn-danger'); + favorite_button.innerHTML = ' Remove favorite'; + + favorite_button.onclick = function(e) { + button.setAttribute('data-state', 'false') + webSocketBridge.send({action: 'unfavorite', event_instance_id: event_instance_id}); + toggleFavoriteButton(button) + } + } else { + favorite_button.classList.remove('btn-danger'); + favorite_button.classList.add('btn-success'); + favorite_button.innerHTML = ' Favorite'; + + favorite_button.onclick = function(e) { + button.setAttribute('data-state', 'true') + webSocketBridge.send({action: 'favorite', event_instance_id: event_instance_id}); + toggleFavoriteButton(button) + } + + } +} + +webSocketBridge.connect('/schedule/'); +webSocketBridge.socket.addEventListener('open', function() { + webSocketBridge.send({action: 'init', camp_slug: '{{ camp.slug }}'}); +}); +webSocketBridge.listen(function(payload, stream) { + if(payload['action'] == 'event_instance') { + event_instance_id = payload['event_instance']['id']; + modal = modals[event_instance_id]; + modal_title = modal.getElementsByClassName('modal-title')[0]; + modal_title.innerHTML = payload['event_instance']['title'] + modal_body_content = modal.getElementsByClassName('modal-body-content')[0]; + modal_body_content.innerHTML = payload['event_instance']['abstract']; + more_button = modal.getElementsByClassName('more-button')[0]; + more_button.setAttribute('href', payload['event_instance']['url']); + favorite_button = modal.getElementsByClassName('favorite-button')[0]; + if(payload['event_instance']['is_favorited'] !== undefined) { + favorite_button.setAttribute('data-state', payload['event_instance']['is_favorited']) + toggleFavoriteButton(favorite_button); + } else { + favorite_button.remove(); + } + + speakers_div = modal.getElementsByClassName('speakers')[0]; + speakers = payload['event_instance']['speakers']; + for(speaker_id in speakers) { + var speaker = speakers[speaker_id]; + var speaker_li = document.createElement('li'); + var speaker_a = document.createElement('a'); + speaker_a.setAttribute('href', speaker['url']); + speaker_a.appendChild(document.createTextNode(speaker['name'])); + speaker_li.appendChild(speaker_a); + speakers_div.appendChild(speaker_li); + } + } +}); + +function openModal(e) { + e.preventDefault(); + + // Avoid that clicking the text in the event will bring up an empty modal + target = e.target; + if (e.target !== this) { + target = e.target.parentElement + } + + event_instance_id = target.dataset['eventinstanceId']; + + modal = modals[event_instance_id]; + + if(modal == undefined) { + template = document.getElementById('event-template'); + modal = template.cloneNode(true); + body = document.getElementsByTagName('body')[0]; + body.appendChild(modal); + modal.setAttribute('id', 'event-modal-' + event_instance_id) + modals[event_instance_id] = modal; + } + + $('#event-modal-' + event_instance_id).modal(); + webSocketBridge.send({action: 'get_event_instance', event_instance_id: event_instance_id}) +} + + +function init_modals(event_class_name) { + var event_elements = document.getElementsByClassName(event_class_name); + + for (var event_id in event_elements) { + event_element = event_elements.item(event_id); + event_element.onclick = openModal + } +} diff --git a/src/program/templates/event_modal.html b/src/program/templates/event_modal.html new file mode 100644 index 00000000..4c80125d --- /dev/null +++ b/src/program/templates/event_modal.html @@ -0,0 +1,22 @@ + diff --git a/src/program/templates/schedule_day.html b/src/program/templates/schedule_day.html index 42a742fc..577a160a 100644 --- a/src/program/templates/schedule_day.html +++ b/src/program/templates/schedule_day.html @@ -1,25 +1,29 @@ {% extends 'schedule_base.html' %} +{% load staticfiles %} {% block schedule_content %} - - -
- {% for timeslot in timeslots %} - - - {% for eventinstance in eventinstances %} - {% if eventinstance.when.lower.time == timeslot.time %} - - {% endif %} - {% endfor %} - - {% endfor %} -
{{ timeslot.time }} - - {{ eventinstance.event.title }}
- {{ eventinstance.when.lower.time }}-{{ eventinstance.when.upper.time }} -
-
- + + {% for timeslot in timeslots %} + + + {% for eventinstance in eventinstances %} + {% if eventinstance.when.lower.time == timeslot.time %} + + {% endif %} + {% endfor %} + + {% endfor %}
{% if timeslot.time.minute == 0 %}{{ timeslot.time }}{% endif %} + + {{ eventinstance.event.title }}
+ {{ eventinstance.when.lower.time }}-{{ eventinstance.when.upper.time }} +
+
+ + {% include "event_modal.html" %} + + + {% endblock %} diff --git a/src/program/templates/schedule_overview.html b/src/program/templates/schedule_overview.html index f95f3ece..d4c29ae8 100644 --- a/src/program/templates/schedule_overview.html +++ b/src/program/templates/schedule_overview.html @@ -3,10 +3,6 @@ {% load commonmark %} {% load staticfiles %} -{% block extra_head %} - -{% endblock %} - {% block schedule_content %} {% if eventinstances %} {% for day in camp.camp_days %} @@ -27,28 +23,12 @@ {% endif %} - + {% include "event_modal.html" %} + + + {% endfor %} @@ -59,102 +39,6 @@ {% endif %} diff --git a/src/static_src/css/bornhack.css b/src/static_src/css/bornhack.css index 14c8f10a..fcacf649 100644 --- a/src/static_src/css/bornhack.css +++ b/src/static_src/css/bornhack.css @@ -163,6 +163,15 @@ footer { border: 1px solid black; } +.event-td { + padding: 5px; + vertical-align: top; + max-width: 200px; + min-width: 200px; + flex-grow: 1; + cursor: pointer; +} + @media (max-width: 520px) { .event { width: 50%; @@ -179,3 +188,13 @@ footer { .fa-select { font-family: 'FontAwesome','Helvetica Neue',Helvetica,Arial,sans-serif; } + +.day-table { + border-collapse: separate; + border-spacing: 1px; +} + +.day-table > tbody > tr > td { + padding: 5px !important; + border: 0 !important; +}