summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorUser Content <content@content.events.ccc.de>2019-10-30 01:11:47 +0000
committerUser Content <content@content.events.ccc.de>2019-10-30 01:11:47 +0000
commite8b020e28ca377868ff8aad8418372debc910ae6 (patch)
tree53f318f05093e9cbde83e91f2c58035aedf2d7f0 /static
Initial commit
Diffstat (limited to 'static')
-rw-r--r--static/rater.css292
-rw-r--r--static/rater.js337
2 files changed, 629 insertions, 0 deletions
diff --git a/static/rater.css b/static/rater.css
new file mode 100644
index 0000000..ae54a13
--- /dev/null
+++ b/static/rater.css
@@ -0,0 +1,292 @@
1body {
2 font-family: "HelveticaNeueLight", "HelveticaNeue-Light", "Helvetica Neue Light", "HelveticaNeue", "Helvetica Neue", 'TeXGyreHerosRegular', "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; font-weight:200; font-stretch:normal;
3}
4
5.username-wrapper {
6 position: absolute;
7 right: 5px;
8}
9
10.changed {
11 background-color: #00f000;
12 color: white;
13}
14
15.clearfix {
16 clear: both;
17}
18
19#event-list {
20 padding-left: 0em;
21 list-style-type: none;
22}
23
24.main-button {
25 vertical-align: top;
26 text-align: center;
27 height: 40px;
28 width: 40px;
29 padding: 0;
30}
31
32.mini-button {
33 margin-right: 0.2em;
34}
35
36button {
37 background-color: #759ae9;
38 background-image: linear-gradient(top, #759ae9 0%, #376fe0 50%, #1a5ad9 50%, #2463de 100%);
39 background-image: -webkit-linear-gradient(top, #759ae9 0%, #376fe0 50%, #1a5ad9 50%, #2463de 100%);
40 border-top: 1px solid #1f58cc;
41 border-right: 1px solid #1b4db3;
42 border-bottom: 1px solid #174299;
43 border-left: 1px solid #1b4db3;
44 border-radius: 4px;
45 box-shadow: inset 0 0 2px 0 rgba(57, 140, 255, 0.8);
46 color: #fff;
47 text-shadow: 0 -1px 1px #1a5ad9;
48}
49
50.event-list-item {
51 vertical-align: top;
52 background-color: #f6f6f6;
53 margin-bottom: 0.5em;
54 border: 1px solid silver;
55 border-radius: 10px;
56 padding: 0 0.5em 0.5em 0.5em;
57 box-sizing: border-box;
58}
59
60.event-list-item[event_state='gone'] {
61 background-image:
62 repeating-linear-gradient(
63 45deg,
64 #eee,
65 #eee 20px,
66 #ddd 20px,
67 #ddd 40px /* determines size */
68 );
69}
70
71.event-list-item[event_type=meeting] .event-title:before { content: 'MEETING '; color: red; font-size: smaller; }
72.event-list-item[event_type=workshop] .event-title:before { content: 'WORKSHOP '; color: red; font-size: smaller; }
73.event-list-item[event_type=concert] .event-title:before { content: 'CONCERT '; color: red; font-size: smaller; }
74.event-list-item[event_type=film] .event-title:before { content: 'FILM '; color: red; font-size: smaller; }
75.event-list-item[event_type=other] .event-title:before { content: 'OTHER '; color: red; font-size: smaller; }
76.event-list-item[event_type=podium] .event-title:before { content: 'PODIUM '; color: red; font-size: smaller; }
77.event-list-item[event_type=performance] .event-title:before { content: 'PERFORMANCE '; color: red; font-size: smaller; }
78.event-list-item[event_type=lightning_talk] .event-title:before { content: 'LIGHTNING '; color: red; font-size: smaller; }
79
80body.two-column .event-list-item {
81 display: inline-block;
82 width: 48%;
83 margin-right: 1%;
84}
85
86body.three-column .event-list-item {
87 display: inline-block;
88 width: 32%;
89 margin-right: 1%;
90}
91
92body.four-column .event-list-item {
93 display: inline-block;
94 width: 23.5%;
95 margin-right: 1%;
96}
97
98.event-rating {
99 display: inline-block;
100 width: 15em;
101 margin: 1em 1em 0 0;
102 padding: 0.2em;
103 background-color: #f0f0f0;
104 border-radius: 10px;
105 vertical-align:top;
106 font-size: smaller;
107}
108
109.event-title,
110.event-subtitle {
111 display: inline;
112 font-weight: bold;
113}
114
115.event-subtitle {
116 font-size: smaller;
117}
118
119.event-rating-comment {
120 min-height: 3em;
121 margin-top: 0.1em;
122 background-color: white;
123}
124
125#Filter, #Username {
126 font-size: x-large;
127 height: 40px;
128}
129
130.label {
131 float: left;
132 min-width: 8em !important;
133 font-style: italic;
134}
135
136.event-persons {
137 margin-top: 0.2em;
138 margin-bottom: 0.2em;
139}
140
141.event-speaker, .event-coordinator {
142 display: inline;
143}
144
145.event-coordinator {
146 margin-right: 0.5em;
147}
148
149.slider {
150 display: inline;
151}
152
153.event-notes,
154.event-description,
155.event-abstract {
156 height: 1.2em;
157 overflow: hidden;
158 cursor: zoom-in;
159 margin-bottom: 0.2em;
160 margin-right: 2em;
161 text-overflow: ellipsis;
162 white-space: nowrap;
163}
164
165.event-notes.full,
166.event-description.full,
167.event-abstract.full {
168 cursor: zoom-out;
169 background: white;
170 overflow: visible;
171 height: auto !important;
172 white-space: initial;
173}
174
175body.only-lectures .lectures-button,
176body.only-todo .todo-button,
177body.show-ratings .ratings-button,
178body.two-column .two-columns,
179body.three-column .three-columns,
180body.four-column .four-columns,
181.event-list-item.editing .edit-button,
182.event-list-item[event_state='accepted'] .accept-button,
183.event-list-item[event_state='rejected'] .reject-button,
184.event-list-item.i-am-coordinator .take-button
185{
186 background-image: -webkit-linear-gradient(top, #f37873 0%, #db504d 50%, #cb0500 50%, #a20601 100%);
187 background-image: linear-gradient(top, #f37873 0%, #db504d 50%, #cb0500 50%, #a20601 100%);
188}
189
190output {
191 margin-left: 1em;
192}
193
194#event-own-rating,
195.event-ratings {
196 display: none;
197 visibility: hidden;
198}
199
200body.show-ratings .event-ratings,
201.event-list-item.editing #event-own-rating {
202 display: block;
203 visibility: initial;
204}
205
206#event-own-rating textarea {
207 min-width: 10em;
208 max-width: 20em;
209 width: 80%;
210}
211
212.event-meter-bar {
213 box-sizing: initial;
214 display: inline;
215 float: left;
216 width: 65px;
217 vertical-align: top;
218 margin: 0;
219 padding: 0;
220}
221
222.has-own-rating .event-meter-bar {
223 height: 65px;
224}
225.has-own-rating .event-meter-bar:after {
226 color: #ff0000;
227 z-index: 1;
228 content: '✓';
229 font-size: 5em;
230 line-height: 1;
231 text-align: center;
232 position: relative;
233 left: 0; top: -65px;
234 width: 65px;
235 height: 65px;
236 opacity: 0.2;
237}
238
239body.safari meter {
240 -webkit-appearance: none;
241 -moz-appearance: none;
242 appearance: none;
243}
244
245meter {
246 vertical-align: top;
247 width: 60px;
248 margin-top: 0.3em;
249 border-radius: 3px;
250 height: 8px;
251
252 -moz-appearance: none;
253}
254
255meter::-moz-meter-bar {
256 background: #ddd;
257}
258
259:-moz-meter-optimum::-moz-meter-bar {
260 background: #afa;
261}
262
263meter.meter-4::-moz-meter-bar {
264 background: #fdd;
265}
266
267meter::-webkit-meter-bar {
268 background: #ddd;
269 box-shadow: 0 2px 3px rgba (0, 0, 0, 0.2) inset;
270 border-radius: 3px;
271}
272
273meter.meter-4::-webkit-meter-bar {
274 background: #fdd;
275}
276
277#status {
278 text-align: center;
279 font-size: xx-large;
280 font-weight: bold;
281 margin-top: 0.5em;
282 width: 100%;
283 clear: both;
284}
285
286body.only-lectures .event-list-item:not([event_type="lecture"]),
287body.only-todo .event-list-item.has-own-rating,
288.filtered,
289.hidden {
290 display: none !important;
291 visibility: hidden !important;
292}
diff --git a/static/rater.js b/static/rater.js
new file mode 100644
index 0000000..ec1bcfe
--- /dev/null
+++ b/static/rater.js
@@ -0,0 +1,337 @@
1function changed_name() {
2 var username = localStorage.getItem("c3-rating-user");
3 var newname = document.getElementById('Username').value;
4 document.getElementById('Username').classList.toggle('changed', username != newname);
5}
6
7function changed_filter() {
8 var filtertext = document.getElementById('Filter').value.toLowerCase();
9 if (filtertext == '') {
10 document.querySelectorAll('.event-list-item.filtered').forEach(function(ev) {
11 ev.classList.remove("filtered");
12 });
13 return;
14 }
15
16 if (!window.inner_texts) {
17 window.inner_texts = {};
18 document.querySelectorAll('.event-list-item').forEach(function(ev) {
19 inner_texts[ev.getAttribute('id')] = ev.innerText.toLowerCase();
20 });
21 }
22
23 Object.keys(window.inner_texts).forEach(function (eid) {
24 var elem = document.getElementById(eid);
25 elem.classList.toggle('filtered', window.inner_texts[eid].indexOf(filtertext) < 0);
26 });
27}
28
29function confirm_name() {
30 localStorage.setItem("c3-rating-user", document.getElementById('Username').value);
31 document.getElementById('Username').classList.remove("changed");
32 update_status();
33}
34
35function toggleHidden(name) {
36 document.getElementById(name).classList.toggle("hidden");
37}
38
39function toggleEdit(eid) {
40 var username = document.getElementById('Username').value;
41 if (!username) {
42 alert( "Please set your name before rating.");
43 return;
44 }
45
46 var ev = document.getElementById('event-'+eid);
47 if (ev.classList.contains('editing')) {
48 ev.classList.toggle('editing', false);
49 return;
50 }
51
52 var other_in_edit = document.getElementsByClassName('editing');
53 if (other_in_edit.length)
54 other_in_edit[0].classList.remove('editing');
55
56 ev.classList.toggle('editing', true);
57
58 var own_rating = document.getElementById('event-own-rating');
59 ev.appendChild(own_rating);
60
61 var myrating = document.querySelectorAll('div#event-rating-'+eid+'[submitter="'+username+'"]');
62 var mycomment = '';
63 if (myrating.length) {
64 mycomment = myrating[0].getElementsByClassName('event-rating-comment')[0].innerHTML;
65 myrating[0].querySelectorAll('meter').forEach(function(meter) {
66 var category = meter.getAttribute('category');
67 document.querySelectorAll('#event-own-rating .slider input[category='+category+']')[0].value = meter.value;
68 changeVal('event-'+category+'-output', meter.value);
69 });
70 } else {
71 document.querySelectorAll('#event-own-rating .slider input').forEach(function(sl) {
72 sl.value = 0;
73 var category = sl.getAttribute('category');
74 changeVal('event-'+category+'-output', '0');
75 });
76 }
77 document.getElementById('event-comment').value = mycomment;
78 own_rating.querySelectorAll('button.remove-rating')[0].classList.toggle('hidden', !myrating.length);
79}
80
81function changeVal(el, value) {
82 document.getElementById(el).innerHTML = value.toString() + " %";
83}
84
85function twocol() {
86 document.body.classList.toggle('two-column');
87 document.body.classList.remove('three-column');
88 document.body.classList.remove('four-column');
89}
90function threecol() {
91 document.body.classList.remove('two-column');
92 document.body.classList.toggle('three-column');
93 document.body.classList.remove('four-column');
94}
95function fourcol() {
96 document.body.classList.remove('two-column');
97 document.body.classList.remove('three-column');
98 document.body.classList.toggle('four-column');
99}
100
101function invert_sort() {
102 var evl = document.getElementById('event-list');
103 var nodes = Array.prototype.slice.call(evl.getElementsByClassName('event-list-item')).reverse().forEach(function(el) {
104 evl.appendChild(el);
105 });
106}
107
108function sort_by(order_function) {
109 var evl = document.getElementById('event-list');
110 Array.prototype.slice.call(evl.getElementsByClassName('event-list-item')).sort(order_function).forEach(function(el) {
111 evl.appendChild(el);
112 });
113}
114
115function myrating_count_sort(elem1, elem2) {
116 var username = document.getElementById('Username').value;
117 return elem2.querySelectorAll('.event-rating[submitter="'+username+'"]').length - elem1.querySelectorAll('.event-rating[submitter="'+username+'"]').length;
118}
119
120function random_sort(elem1, elem2) { return !!Math.floor(Math.random() * 2) ? -1 : 1; }
121function rating_count_sort(elem1, elem2) { return elem2.querySelectorAll('.event-rating').length - elem1.querySelectorAll('.event-rating').length; }
122function rating_1_sort(elem1, elem2) { return elem2.getElementsByClassName('meter-0')[0].getAttribute('value') - elem1.getElementsByClassName('meter-0')[0].getAttribute('value'); }
123function rating_2_sort(elem1, elem2) { return elem2.getElementsByClassName('meter-1')[0].getAttribute('value') - elem1.getElementsByClassName('meter-1')[0].getAttribute('value'); }
124function rating_3_sort(elem1, elem2) { return elem2.getElementsByClassName('meter-2')[0].getAttribute('value') - elem1.getElementsByClassName('meter-2')[0].getAttribute('value'); }
125function rating_4_sort(elem1, elem2) { return elem2.getElementsByClassName('meter-3')[0].getAttribute('value') - elem1.getElementsByClassName('meter-3')[0].getAttribute('value'); }
126function rating_5_sort(elem1, elem2) { return elem2.getElementsByClassName('meter-4')[0].getAttribute('value') - elem1.getElementsByClassName('meter-4')[0].getAttribute('value'); }
127function coordinator_sort(elem1, elem2) { return get_coordinator(elem1).localeCompare(get_coordinator(elem2)); }
128function state_sort(elem1, elem2) { return elem2.getAttribute('event_state').localeCompare(elem1.getAttribute('event_state')); }
129
130function get_coordinator(elem) {
131 var coordinator = elem.getElementsByClassName('event-coordinator');
132 if (coordinator.length)
133 return coordinator[0].getAttribute('coordinator');
134 return '';
135}
136
137function do_remove_rating() {
138 if (confirm('are you sure?') == false)
139 return;
140
141 var in_edit = document.getElementsByClassName('editing');
142 if (!in_edit.length)
143 return;
144 var eid = in_edit[0].getAttribute('id').replace(/^event-/, '');
145
146 var xhttp = new XMLHttpRequest();
147 xhttp.open("POST", "api/remove_rating/"+eid, true);
148 xhttp.setRequestHeader("Content-type", "application/json");
149
150 var username = document.getElementById('Username').value;
151
152 xhttp.onreadystatechange = function() {
153 if (xhttp.readyState == XMLHttpRequest.DONE && xhttp.status == 200) {
154 var myrating = document.querySelectorAll('div#event-rating-'+eid+'[submitter="'+username+'"]');
155 if(myrating.length)
156 myrating[0].parentNode.removeChild(myrating[0]);
157 toggleEdit(eid);
158 update_status();
159 }
160 }
161 xhttp.send( JSON.stringify( { 'author': username } ) );
162}
163
164function do_remove_event(eid) {
165 var ev = document.getElementById('event-'+eid);
166 var xhttp = new XMLHttpRequest();
167 xhttp.open("POST", "api/remove_event/"+eid, true);
168 xhttp.setRequestHeader("Content-type", "application/json");
169 xhttp.onreadystatechange = function() {
170 if (xhttp.readyState == XMLHttpRequest.DONE && xhttp.status == 200) {
171 ev.parentNode.removeChild(ev);
172 }
173 }
174 xhttp.send();
175}
176
177function do_rate() {
178 var in_edit = document.getElementsByClassName('editing');
179 if (!in_edit.length)
180 return;
181 var eid = in_edit[0].getAttribute('id').replace(/^event-/, '');
182
183 var username = document.getElementById('Username').value;
184 if (!username) {
185 alert( "Please set your name before rating.");
186 return;
187 }
188
189 var xhttp = new XMLHttpRequest();
190 xhttp.open("POST", "api/add_rating/"+eid, true);
191 xhttp.setRequestHeader("Content-type", "application/json");
192
193 ratings = {};
194 document.getElementById('event-own-rating').querySelectorAll('.category-slider input').forEach(function(ev) {
195 ratings[ev.getAttribute("category")] = ev.value;
196 });
197 var comment = document.getElementById('event-comment').value;
198
199 xhttp.onreadystatechange = function() {
200 if (xhttp.readyState == XMLHttpRequest.DONE && xhttp.status == 200) {
201 var myrating = document.querySelectorAll('div#event-rating-'+eid+'[submitter="'+username+'"]');
202 if (myrating.length) {
203 myrating = myrating[0];
204 } else {
205 myrating = document.getElementById('event-rating-new').cloneNode(true);
206 myrating.setAttribute('id', 'event-rating-'+eid);
207 myrating.classList.remove('hidden');
208 myrating.setAttribute('submitter', username);
209 myrating.getElementsByClassName('event-rating-submitter')[0].innerHTML = username + ':';
210 document.querySelectorAll('#event-'+eid+' .event-ratings')[0].append(myrating);
211 }
212 myrating.getElementsByClassName('event-rating-comment')[0].innerHTML = comment;
213 for (category in ratings) {
214 myrating.querySelectorAll('meter[category='+category+']')[0].value = ratings[category];
215 myrating.querySelectorAll('.event-rating-category-output[category='+category+']')[0].innerHTML = ' ' + categories[category] + ' ' + ratings[category] + ' %';
216 }
217
218 toggleEdit(eid);
219 update_status();
220 }
221 }
222
223 xhttp.send( JSON.stringify( {
224 'author': username,
225 'comment': comment,
226 'ratings': ratings
227 } ) );
228}
229
230function do_set_state(eid, state) {
231 if ( state == document.getElementById('event-'+eid).getAttribute('event_state'))
232 state = '';
233
234 var xhttp = new XMLHttpRequest();
235 xhttp.open("POST", "api/set_event_state/"+eid, true);
236 xhttp.setRequestHeader("Content-type", "application/json");
237 xhttp.onreadystatechange = function() {
238 if (xhttp.readyState == XMLHttpRequest.DONE && xhttp.status == 200) {
239 document.getElementById('event-'+eid).setAttribute('event_state', state);
240 update_status();
241 }
242 }
243 xhttp.send( JSON.stringify( { 'state': state } ) );
244}
245
246function do_take(eid) {
247 var username = document.getElementById('Username').value;
248 if (!username) {
249 alert( "Please set your name before taking an event.");
250 return;
251 }
252
253 var ev = document.getElementById('event-'+eid);
254 if (ev.classList.contains('i-am-coordinator'))
255 username = '';
256
257 var xhttp = new XMLHttpRequest();
258 xhttp.open("POST", "api/set_event_coordinator/"+eid, true);
259 xhttp.setRequestHeader("Content-type", "application/json");
260 xhttp.onreadystatechange = function() {
261 if (xhttp.readyState == XMLHttpRequest.DONE && xhttp.status == 200) {
262 var coor = ev.getElementsByClassName('event-coordinator');
263 if (coor.length) {
264 if (username) {
265 coor[0].innerHTML = '<em>coordinator: </em> '+username;
266 coor[0].setAttribute('coordinator', username);
267 } else
268 coor[0].parentNode.removeChild(coor[0]);
269 } else {
270 if (username) {
271 var pers = ev.getElementsByClassName('event-persons');
272 coor = document.createElement('div');
273 coor.classList.toggle('event-coordinator', true);
274 coor.setAttribute('coordinator', username);
275 coor.innerHTML = '<em>coordinator: </em> '+username;
276 pers[0].insertBefore(coor, pers[0].firstChild);
277 }
278 }
279 update_status();
280 }
281 }
282 xhttp.send( JSON.stringify( { 'coordinator': username } ) );
283}
284
285function update_status() {
286 var accepted_count = document.querySelectorAll('.event-list-item[event_state=accepted]').length;
287 var rejected_count = document.querySelectorAll('.event-list-item[event_state=rejected]').length;
288 var taken_count = document.querySelectorAll('.event-list-item .event-coordinator').length;
289 var total_count = document.getElementsByClassName('event-list-item').length;
290 var total_voted_count = document.querySelectorAll('.event-rating:first-child').length;
291 var username = document.getElementById('Username').value;
292 var own_voted_count = 0;
293 if (username)
294 own_voted_count = document.querySelectorAll('.event-rating[submitter="'+username+'"]').length;
295 document.getElementById('status').innerHTML = total_count + ' events. ' + accepted_count + ' accepted. ' + rejected_count + ' rejected. ' + (total_count - own_voted_count) + ' todo. ' + (total_count - total_voted_count) + ' unvoted. ' + (total_count - taken_count) + ' untaken.';
296
297 /* Do the math */
298 document.querySelectorAll('.event-list-item').forEach(function(ev) {
299 if (username) {
300 ev.classList.toggle('has-own-rating', ev.querySelectorAll('.event-rating[submitter="'+username+'"]').length > 0);
301 ev.classList.toggle('i-am-coordinator', ev.querySelectorAll('.event-coordinator[coordinator="'+username+'"]').length > 0);
302 }
303
304 var counts = {};
305 var meters = ev.querySelectorAll('.event-rating meter');
306
307 if (!meters.length) {
308 ev.querySelectorAll('.top-meter').forEach(function(meter) {
309 meter.setAttribute('value', 0);
310 });
311 return;
312 }
313
314 meters.forEach(function(rat) {
315 var tmp = counts[rat.getAttribute('category')] || 0;
316 counts[rat.getAttribute('category')] = tmp + parseInt(rat.getAttribute('value'));
317 });
318 var total = 0, i = 0, divisor = meters.length / Object.keys(counts).length;
319 for (category in counts) {
320 var dest_meter = ev.getElementsByClassName('meter-'+i)[0];
321 dest_meter.setAttribute('value', counts[category] / divisor);
322 dest_meter.setAttribute('title', category + ': ' + counts[category] / divisor + ' %' );
323 total += counts[category] / divisor;
324 i++;
325 }
326 ev.getElementsByClassName('meter-4')[0].setAttribute('value', total / Object.keys(counts).length);
327 });
328}
329
330document.addEventListener('DOMContentLoaded', function () {
331 var username = localStorage.getItem("c3-rating-user");
332 if (username)
333 document.getElementById('Username').value = username;
334 if (window.safari !== undefined)
335 document.body.classList.add('safari');
336 update_status();
337});