#52: Added countdown on projector view with control unit (agenda overview) and time variable (general settings).
This commit is contained in:
parent
52c24d6a48
commit
076699ff45
@ -12,7 +12,6 @@
|
||||
<script type="text/javascript" src="/static/javascript/tabledrag.js"></script>
|
||||
<script type="text/javascript" src="/static/javascript/knockout-1.2.1.js"></script>
|
||||
<script type="text/javascript" src="/static/javascript/agenda.js"></script>
|
||||
<script type="text/html" src="/static/javascript/agenda.slideTemplate.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--//--><![CDATA[//><!--
|
||||
@ -48,13 +47,27 @@
|
||||
<input type="button" onclick="window.location.href='{% url item_overview %}';" value="{%trans 'No' %}">
|
||||
</em>
|
||||
</div>
|
||||
<div style="text-align:right; padding-bottom:3px;">
|
||||
|
||||
<div style="text-align: right; padding: 0 5px 5px 0; margin-top:-20px;">
|
||||
<!-- countdown -->
|
||||
<input type="checkbox" name="countdown" onchange="document.location='{% if countdown_visible == "True" %}{% url countdown_close %}{% else %}{% url countdown_open %}{% endif %}'"
|
||||
{% if countdown_visible == "True" %}checked{% endif %}>
|
||||
{% trans "Countdown" %} ({{countdown_time}} {% trans "sec" %}){% if countdown_visible == "True" %}:
|
||||
<a class="beamer_countdown" href="{% url countdown_reset countdown_time %}" title="{% trans 'Reset countdown' %}"><img src="/static/images/icons/media-skip-backward.png"></a>
|
||||
<a class="beamer_countdown" href="{% url countdown_start %}" title="{% trans 'Start countdown' %}"><img src="/static/images/icons/media-playback-start.png"></a>
|
||||
<a class="beamer_countdown" href="{% url countdown_stop %}" title="{% trans 'Stop countdown' %}"><img src="/static/images/icons/media-playback-pause.png"></a>
|
||||
{% endif %}
|
||||
<p></p>
|
||||
<!-- beamer control -->
|
||||
{% trans "Adjust projector view" %}:
|
||||
<a class="beamer_edit" href="{% url beamer_bigger %}"><img src="/static/images/icons/zoom-in.png"></a> <a class="beamer_edit" href="{% url beamer_smaller %}"><img src="/static/images/icons/zoom-out.png"></a>
|
||||
<a class="beamer_edit" href="{% url beamer_up %}"><img src="/static/images/icons/go-up.png"></a> <a class="beamer_edit" href="{% url beamer_down %}"><img src="/static/images/icons/go-down.png"></a>
|
||||
<a class="beamer_edit" href="{% url beamer_clean %}"><img src="/static/images/icons/view-restore.png"></a>
|
||||
<a class="beamer_edit" href="{% url beamer_bigger %}" title="{% trans 'Zoom in' %}"><img src="/static/images/icons/zoom-in.png"></a>
|
||||
<a class="beamer_edit" href="{% url beamer_smaller %}" title="{% trans 'Zoom out' %}"><img src="/static/images/icons/zoom-out.png"></a>
|
||||
<a class="beamer_edit" href="{% url beamer_up %}" title="{% trans 'Scroll text up' %}"><img src="/static/images/icons/go-up.png"></a>
|
||||
<a class="beamer_edit" href="{% url beamer_down %}" title="{% trans 'Scroll text down' %}"><img src="/static/images/icons/go-down.png"></a>
|
||||
<a class="beamer_edit" href="{% url beamer_clean %}" title="{% trans 'Reset projector view' %}"><img src="/static/images/icons/view-restore.png"></a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table id="menu-overview" class="agendatable">
|
||||
<tr>
|
||||
{% if perms.agenda.can_manage_agenda %}
|
||||
@ -153,7 +166,7 @@
|
||||
<td style="width: 1px;white-space: nowrap;">
|
||||
<a href="{{ item.get_absolute_url }}"><img src="/static/images/icons/document-preview.png" title="{% trans 'Show projector preview' %}"></a>
|
||||
|
||||
{% if perms.agenda.can_manage_agenda %}
|
||||
{% if perms.agenda.can_manage_agenda %}
|
||||
<a href="{% url item_edit item.id %}"><img src="/static/images/icons/document-edit.png" title="{% trans 'Edit item' %}"></a>
|
||||
<a href="{% url item_delete item.id %}"><img src="/static/images/icons/edit-delete.png" title="{% trans 'Delete item' %}"></a>
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
{% now "H:i" %}
|
||||
</div>
|
||||
|
||||
<div id="countdown">0:00</div>
|
||||
|
||||
<div id="content">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
@ -66,4 +66,14 @@ urlpatterns = patterns('agenda.views',
|
||||
url(r'^beamer/down$', 'beamer_edit', {'direction': 'down'}, name='beamer_down'),
|
||||
|
||||
url(r'^beamer/clean$', 'beamer_edit', {'direction': 'clean'}, name='beamer_clean'),
|
||||
|
||||
url(r'^beamer/countdown/show$', 'beamer_countdown', {'command': 'show'}, name='countdown_open'),
|
||||
|
||||
url(r'^beamer/countdown/hide$', 'beamer_countdown', {'command': 'hide'}, name='countdown_close'),
|
||||
|
||||
url(r'^beamer/countdown/reset/(?P<time>\d+)$', 'beamer_countdown', {'command': 'reset'}, name='countdown_reset'),
|
||||
|
||||
url(r'^beamer/countdown/start$', 'beamer_countdown', {'command': 'start'}, name='countdown_start'),
|
||||
|
||||
url(r'^beamer/countdown/stop$', 'beamer_countdown', {'command': 'stop'}, name='countdown_stop'),
|
||||
)
|
||||
|
@ -83,7 +83,11 @@ def beamer(request):
|
||||
'title': data['title'],
|
||||
'time': datetime.now().strftime('%H:%M'),
|
||||
'bigger': config_get('bigger'),
|
||||
'up': config_get('up')}
|
||||
'up': config_get('up'),
|
||||
'countdown_visible': config_get('countdown_visible'),
|
||||
'countdown_time': config_get('agenda_countdown_time'),
|
||||
'countdown_control': config_get('countdown_control'),
|
||||
}
|
||||
return ajax_request(jsondata)
|
||||
else:
|
||||
return render_to_response(template,
|
||||
@ -108,6 +112,27 @@ def beamer_edit(request, direction):
|
||||
return ajax_request({})
|
||||
return redirect(reverse('item_overview'))
|
||||
|
||||
@permission_required('agenda.can_manage_agenda')
|
||||
def beamer_countdown(request, command, time=60):
|
||||
if command == 'show':
|
||||
config_set('countdown_visible', True)
|
||||
elif command == 'hide':
|
||||
config_set('countdown_visible', False)
|
||||
elif command == 'reset':
|
||||
config_set('countdown_control', 'reset')
|
||||
elif command == 'start':
|
||||
config_set('countdown_control', 'start')
|
||||
elif command == 'stop':
|
||||
config_set('countdown_control', 'stop')
|
||||
|
||||
if request.is_ajax():
|
||||
if command == "show":
|
||||
link = reverse('countdown_close')
|
||||
else:
|
||||
link = reverse('countdown_open')
|
||||
return ajax_request({'countdown_visible': config_get('countdown_visible'),
|
||||
'link': link})
|
||||
return redirect(reverse('item_overview'))
|
||||
|
||||
def assignment_votes(item):
|
||||
votes = []
|
||||
@ -170,7 +195,9 @@ def overview(request):
|
||||
'items': items,
|
||||
'items_hidden': items_hidden,
|
||||
'overview': overview,
|
||||
'summary': is_summary()
|
||||
'summary': is_summary(),
|
||||
'countdown_visible': config_get('countdown_visible'),
|
||||
'countdown_time': config_get('agenda_countdown_time'),
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,7 +104,7 @@ $(function() {
|
||||
hideClosedSlides(true);
|
||||
}
|
||||
|
||||
// controll beamer
|
||||
// control beamer
|
||||
$('.beamer_edit').click(function(event) {
|
||||
event.preventDefault();
|
||||
link = $(this);
|
||||
@ -117,5 +117,35 @@ $(function() {
|
||||
});
|
||||
});
|
||||
|
||||
// control countdown
|
||||
$('.beamer_countdown').click(function(event) {
|
||||
event.preventDefault();
|
||||
link = $(this);
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: link.attr('href'),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
}
|
||||
});
|
||||
});
|
||||
$('.countdown_visible_link').click(function(event) {
|
||||
event.preventDefault();
|
||||
link = $(this);
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: link.attr('href'),
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if (data.countdown_visible == "True") {
|
||||
newclass = 'open';
|
||||
} else {
|
||||
newclass = 'closed';
|
||||
}
|
||||
link.removeClass('closed open').addClass(newclass);
|
||||
link.attr('href', data.link);
|
||||
}
|
||||
});
|
||||
});
|
||||
ko.applyBindings(ViewModel);
|
||||
});
|
||||
|
@ -14,6 +14,18 @@ function presentation_reload() {
|
||||
$('#content li').css({'font-size': data.bigger + '%'}, 200);
|
||||
$('#content #sidebar').css({'font-size': '16px'}, 0);
|
||||
$('#content').animate({'margin-top': data.up + 'em'}, 200);
|
||||
if (data.countdown_visible == "True")
|
||||
$('#countdown').slideDown();
|
||||
if (data.countdown_visible == "False")
|
||||
$('#countdown').slideUp();
|
||||
if (data.countdown_control == "reset")
|
||||
resetTimer(data.countdown_time);
|
||||
if (data.countdown_control == 'start') {
|
||||
if (!timer_is_running)
|
||||
startTimer();
|
||||
}
|
||||
if (data.countdown_control == 'stop')
|
||||
stopTimer();
|
||||
setTimeout("presentation_reload()", 500);
|
||||
},
|
||||
error: function () {
|
||||
@ -38,3 +50,47 @@ $(document).ready(function() {
|
||||
switchajax();
|
||||
presentation_reload();
|
||||
});
|
||||
|
||||
// *** Countdown variables and functions ***
|
||||
var timer_value;
|
||||
var timer_is_running=false;
|
||||
var timer_is_visible=false;
|
||||
var timerIntervalId;
|
||||
|
||||
function resetTimer(value) {
|
||||
stopTimer()
|
||||
timer_value = value;
|
||||
updateTimer();
|
||||
}
|
||||
function stopTimer() {
|
||||
timer_is_running = false;
|
||||
clearInterval(timerIntervalId);
|
||||
}
|
||||
|
||||
function startTimer() {
|
||||
timer_is_running = true;
|
||||
if (timer_value > 0) {
|
||||
timerIntervalId = setInterval("decrementTimer()", 1000);
|
||||
}
|
||||
}
|
||||
function decrementTimer() {
|
||||
timer_value--;
|
||||
if (timer_value <= 0) {
|
||||
timer_value = 0;
|
||||
stopTimer();
|
||||
}
|
||||
updateTimer();
|
||||
}
|
||||
function convertSeconds(s) {
|
||||
var m = Math.floor(s / 60);
|
||||
s %= 60;
|
||||
var h = Math.floor(m / 60);
|
||||
m %= 60;
|
||||
return (h>0?h+':':'') + (h>0&&m<10?'0':'') + m + ':' + (s<10?'0':'') + s;
|
||||
}
|
||||
|
||||
function updateTimer() {
|
||||
if (timer_value >= 0) {
|
||||
$("#countdown").html(convertSeconds(timer_value));
|
||||
}
|
||||
}
|
@ -47,3 +47,19 @@ a.hidelink.show div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
a.countdown_visible_link.closed div {
|
||||
background-image: url(/static/images/icons/user-offline.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
a.countdown_visible_link.open div {
|
||||
background-image: url(/static/images/icons/user-online.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
}
|
@ -56,10 +56,22 @@ body{
|
||||
padding-left:30px;
|
||||
background: url(../images/icons/clock.png) no-repeat scroll 0px 4px;
|
||||
}
|
||||
|
||||
#currentTime.ajax_error {
|
||||
border-bottom: 4px solid red;
|
||||
}
|
||||
#countdown {
|
||||
display: none;
|
||||
font-size: 4em;
|
||||
font-weight: bold;
|
||||
padding: 0 1em;
|
||||
position: fixed;
|
||||
right: 40px;
|
||||
top: 0;
|
||||
background: #DDD9D9;
|
||||
border-bottom-left-radius: 0.75em;
|
||||
border-bottom-right-radius: 0.75em;
|
||||
}
|
||||
|
||||
|
||||
/*** CONTENT ***/
|
||||
#content {
|
||||
|
@ -32,6 +32,12 @@ class EventConfigForm(Form):
|
||||
event_location = CharField(widget=TextInput(), required=False, label=_("Event location"))
|
||||
event_organizer = CharField(widget=TextInput(), required=False, label=_("Event organizer"))
|
||||
|
||||
class AgendaConfigForm(Form):
|
||||
error_css_class = 'error'
|
||||
required_css_class = 'required'
|
||||
|
||||
agenda_countdown_time = IntegerField(widget=TextInput(attrs={'class':'small-input'}),label=_("Countdown (in seconds)"),initial=60, min_value=0)
|
||||
|
||||
class ApplicationConfigForm(Form):
|
||||
error_css_class = 'error'
|
||||
required_css_class = 'required'
|
||||
|
@ -16,6 +16,7 @@ from django.utils.translation import ugettext as _
|
||||
DEFAULT_DATA = {
|
||||
'event_name': 'OpenSlides',
|
||||
'event_description': 'Presentation and voting system',
|
||||
'agenda_countdown_time': 60,
|
||||
'application_min_supporters': 4,
|
||||
'application_preamble': 'Die Versammlung möge beschließen,',
|
||||
'application_pdf_title': _('Applications'),
|
||||
|
@ -9,6 +9,11 @@
|
||||
{{ form_event.as_p }}
|
||||
</fieldset>
|
||||
<p></p>
|
||||
<fieldset>
|
||||
<legend>{%trans "Agenda" %}</legend>
|
||||
{{ form_agenda.as_p }}
|
||||
</fieldset>
|
||||
<p></p>
|
||||
<fieldset>
|
||||
<legend>{%trans "Application" %}</legend>
|
||||
{{ form_application.as_p }}
|
||||
|
@ -16,7 +16,7 @@ from django.contrib import messages
|
||||
from django.utils.translation import ugettext as _
|
||||
from utils.utils import template
|
||||
from utils.utils import template, permission_required
|
||||
from system.forms import SystemConfigForm, EventConfigForm, ApplicationConfigForm, AssignmentConfigForm
|
||||
from system.forms import SystemConfigForm, EventConfigForm, AgendaConfigForm, ApplicationConfigForm, AssignmentConfigForm
|
||||
from system.api import config_get, config_set
|
||||
|
||||
@permission_required('system.can_manage_system')
|
||||
@ -45,15 +45,18 @@ def get_system_config(request):
|
||||
def get_general_config(request):
|
||||
if request.method == 'POST':
|
||||
form_event = EventConfigForm(request.POST, prefix='event')
|
||||
form_agenda = AgendaConfigForm(request.POST, prefix='agenda')
|
||||
form_application = ApplicationConfigForm(request.POST, prefix='application')
|
||||
form_assignment = AssignmentConfigForm(request.POST, prefix='assignment')
|
||||
if form_event.is_valid() and form_application.is_valid() and form_assignment.is_valid():
|
||||
if form_event.is_valid() and form_agenda.is_valid() and form_application.is_valid() and form_assignment.is_valid():
|
||||
# event form
|
||||
config_set('event_name', form_event.cleaned_data['event_name'])
|
||||
config_set('event_description', form_event.cleaned_data['event_description'])
|
||||
config_set('event_date', form_event.cleaned_data['event_date'])
|
||||
config_set('event_location', form_event.cleaned_data['event_location'])
|
||||
config_set('event_organizer', form_event.cleaned_data['event_organizer'])
|
||||
# agenda form
|
||||
config_set('agenda_countdown_time', form_agenda.cleaned_data['agenda_countdown_time'])
|
||||
# application form
|
||||
config_set('application_min_supporters', form_application.cleaned_data['application_min_supporters'])
|
||||
config_set('application_preamble', form_application.cleaned_data['application_preamble'])
|
||||
@ -78,6 +81,9 @@ def get_general_config(request):
|
||||
'event_location': config_get('event_location'),
|
||||
'event_organizer': config_get('event_organizer'),
|
||||
}, prefix='event')
|
||||
form_agenda = AgendaConfigForm(initial={
|
||||
'agenda_countdown_time': config_get('agenda_countdown_time'),
|
||||
}, prefix='agenda')
|
||||
form_application = ApplicationConfigForm(initial={
|
||||
'application_min_supporters': config_get('application_min_supporters'),
|
||||
'application_preamble': config_get('application_preamble'),
|
||||
@ -94,6 +100,7 @@ def get_general_config(request):
|
||||
}, prefix='assignment')
|
||||
return {
|
||||
'form_event': form_event,
|
||||
'form_agenda': form_agenda,
|
||||
'form_application': form_application,
|
||||
'form_assignment': form_assignment,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user