jekyll-theme-conference 3.0.1 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77630ecb9f0ae81a9f53c52bf08d86fda4be6a75e92668e95f0a5f48ed270748
4
- data.tar.gz: 32ff767339f60c06bff39b86cbf2d1126f1c149ab797a26f1b1ec9fcdfc49223
3
+ metadata.gz: 91444cf0a7c14c4e1d4a10547c95fd9c6a10b176db297a2071830f2a634052c0
4
+ data.tar.gz: 5c16b5f374876f5bde05ff91c0e121133843f31ad42701ef8336b523933101ba
5
5
  SHA512:
6
- metadata.gz: 6b0edcba1a9c41fc6365312f1cba5056ce66dd351283a9af19266d558fe27dac3b01d2fa0f83a0567eacc293f91489b1af7922e868325f23b19996a6608b0ec9
7
- data.tar.gz: 18c8a4f2e500b45d1e4ddba54eeb466b4b2b3d7bf9171554c15403f8e58812f7f06bd06f1864e25cf9b792811fcd6b0ad16c1448088d727b6c57ac1246dea23b
6
+ metadata.gz: c2e410318beee836c5d3371185d5e5386f24a28c34061eeb0fc407ec68715326e55f9344021b93c2ded7631df376c45723fbeac84a3e7ae9c5f7a781e981abcc
7
+ data.tar.gz: a3a3fefe3e080e42fdf24923fe36189593aeaafd87a2e90624ce42a2fa6ba766a5436201cbb63a5e7b34fba71ea695e05a9ddbadf13352fddc4792c8423444f9
data/README.md CHANGED
@@ -18,6 +18,41 @@ The theme was originally created for the yearly Winterkongress conference of the
18
18
  - [Demo: Winterkongress](https://digitale-gesellschaft.ch/kongress/)
19
19
 
20
20
 
21
+ ## Table of Contents
22
+
23
+ - [Installation](#installation)
24
+ * [Gem-based Method](#gem-based-method)
25
+ * [Remote Theme Method](#remote-theme-method)
26
+ - [Setup](#setup)
27
+ * [Jump Start](#jump-start)
28
+ * [Automatic Import](#automatic-import)
29
+ * [Automatic Build](#automatic-build)
30
+ - [Configuration](#configuration)
31
+ * [Theme Verification](#theme-verification)
32
+ * [Collection URLs](#collection-urls)
33
+ * [Language](#language)
34
+ * [Navigation Bar](#navigation-bar)
35
+ * [Main Landing Page](#main-landing-page)
36
+ * [Information Boxes](#information-boxes)
37
+ * [Live Indications & Streaming](#live-indications---streaming)
38
+ * [Talk Settings](#talk-settings)
39
+ * [Speaker Settings](#speaker-settings)
40
+ * [Location Settings](#location-settings)
41
+ * [Program Settings](#program-settings)
42
+ - [Content](#content)
43
+ * [Schedule / Program](#schedule---program)
44
+ * [Talks](#talks)
45
+ * [Speakers](#speakers)
46
+ * [Rooms](#rooms)
47
+ * [Links](#links)
48
+ - [Overview Pages](#overview-pages)
49
+ * [Location / Room Overview](#location---room-overview)
50
+ * [Live Stream Overview](#live-stream-overview)
51
+ * [Additional Pages](#additional-pages)
52
+ - [Design](#design)
53
+ - [License](#license)
54
+
55
+
21
56
  ## Installation
22
57
 
23
58
  There are three ways to install: As a [Gem-based theme](https://jekyllrb.com/docs/themes/#understanding-gem-based-themes), as a [remote theme](https://github.blog/2017-11-29-use-any-theme-with-github-pages/) (GitHub Pages compatible), or by cloning/forking this repository and reference to it directly.
@@ -319,15 +354,16 @@ conference:
319
354
 
320
355
  In order to help users navigating the program during the congress, a _Live_ indication can be shown next to talks which are currently taking place. A small JavaScript functions keeps the site automatically up-to-date (without the need to refresh) showing the indication as soon as the talk has started and hiding it once it is over (according to the timetable indicated in the `_data/program.yml` file).
321
356
 
322
- This can be further extended if some of the talks have an associated live stream: Upon clicking one of the live indications a modal will open containing the corresponding live stream embedded. The URL to the live stream has to be set via `live` property in each room (see the _Content_ > _Room_ section below).
357
+ This can be further extended if some of the talks have an associated live stream: Upon clicking one of the live indications a modal will open containing the corresponding live stream embedded. The URL to the live stream has to be set via `live` property in each room (see the _Content_ > _Room_ section below). Instead of opening the modal an external link can also be used.
323
358
 
324
359
  In order to activate the functionality, each day in the `program.yml` file must contain a `date` property (see section _Content_ > _Schedule / Program_ below) and the `live` property has to be set in the configuration file containing
325
360
 
326
361
  - how long a pause between two consecutive talks has to be for the live indication to pause (`time_stop`),
327
362
  - optionally if streaming is enabled (`streaming`) with indications
328
363
  + how many minutes the stream goes active before a talk (`time_prepend`),
329
- + how many minutes the stream stays active after a talk (`time_extend`), and
330
- + how long a pause between two consecutive talks has to be for the stream to pause (`time_pause`),
364
+ + how many minutes the stream stays active after a talk (`time_extend`),
365
+ + how long a pause between two consecutive talks has to be for the stream to pause (`time_pause`), and
366
+ + optionally an external (absolute) link to which the user will be redirected instead of opening the modal (`external`),
331
367
  - optionally a demo mode setting, whereby the JavaScript function cycles through the entire program in five minutes for demonstration purposes (`demo: true`, default: `false`).
332
368
 
333
369
  ```yaml
@@ -587,6 +623,10 @@ If you choose a different location for the overview pages you must:
587
623
 
588
624
  The `location` layout contains a map container (if not disabled, see section _Location Settings_ above) which can be customized. See the section above for further details.
589
625
 
626
+ ### Live Stream Overview
627
+
628
+ The `stream-overview` layout contains all active streams on a single page (see the section _Live Indications & Streaming_ above).
629
+
590
630
  ### Additional Pages
591
631
 
592
632
  Additional static pages can easily be added as files and linked to via navigation bar or main landing page (see above on how to).
@@ -13,6 +13,8 @@ window.conference.live = (function() {
13
13
  {%- include partials/get_talk_timestamp.html -%}
14
14
  {%- assign conf_end = timestamp_end -%}
15
15
 
16
+ let data;
17
+
16
18
  let confStart = {{ conf_start }};
17
19
  let confEnd = {{ conf_end }};
18
20
  let confDur = confEnd - confStart;
@@ -32,26 +34,43 @@ window.conference.live = (function() {
32
34
  let streamVideoTimer;
33
35
  let streamInfoTimer;
34
36
 
37
+ let loadData = function () {
38
+ // Fetch schedule from external file
39
+ $.getJSON('{{ site.baseurl }}/assets/js/data.json', function(json) {
40
+ data = json;
41
+ });
42
+ };
43
+
44
+ let getData = function () {
45
+ // Return data
46
+ return data;
47
+ };
48
+
35
49
  let mod = function (n, m) {
50
+ // Absolute modulo
36
51
  return ((n % m) + m) % m;
37
52
  };
38
53
 
39
54
  let timeNow = function () {
55
+ // Current timestamp in seconds
40
56
  return Math.floor(Date.now() / 1000);
41
57
  };
42
58
 
43
59
  let timeCont = function () {
60
+ // Continuous time (respecting previous pauses)
44
61
  return timeNow() - timeOffset;
45
62
  };
46
63
 
47
64
  let timeCycle = function () {
65
+ // Cyclic timestamp in seconds
48
66
  let actTime = timeNow();
49
- let relTime = mod(actTime, durDemo + 2*durPause) / durDemo;
67
+ let relTime = mod(actTime, durDemo + 2*durPause) / (durDemo + 2*durPause);
50
68
  let cycleTime = mod((demoEnd - demoStart) * relTime - timeOffset, (demoEnd - demoStart)) + demoStart;
51
69
  return cycleTime;
52
70
  };
53
71
 
54
72
  let time = function () {
73
+ // Return app time
55
74
  if (freezeTime) {
56
75
  return timeFrozen;
57
76
  }
@@ -64,6 +83,7 @@ window.conference.live = (function() {
64
83
  };
65
84
 
66
85
  let pauseTime = function () {
86
+ // Pause app time
67
87
  if (!freezeTime) {
68
88
  timeFrozen = time();
69
89
  freezeTime = true;
@@ -73,6 +93,7 @@ window.conference.live = (function() {
73
93
  };
74
94
 
75
95
  let continueTime = function () {
96
+ // Continue app time
76
97
  if (freezeTime) {
77
98
  freezeTime = false;
78
99
  timeOffset += time() - timeFrozen;
@@ -80,18 +101,23 @@ window.conference.live = (function() {
80
101
  }
81
102
  };
82
103
 
83
- let resetTime = function (timeStr) {
104
+ let resetTime = function () {
105
+ // Reset app time
84
106
  timeOffset = 0;
85
107
  freezeTime = false;
86
108
 
87
109
  startUpdate();
88
110
  };
89
111
 
90
- let setTime = function (newTime, newDay=1) {
112
+ let setTime = function (newTime, newDay) {
113
+ // Set and pause app time
91
114
  pauseTime();
92
115
 
93
116
  let dayIdx;
94
- if (Number.isInteger(newDay)) {
117
+ if (arguments.length < 2) {
118
+ dayIdx = 0;
119
+ }
120
+ else if (Number.isInteger(newDay)) {
95
121
  dayIdx = newDay-1;
96
122
  }
97
123
  else if (/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(newDay)) {
@@ -100,7 +126,7 @@ window.conference.live = (function() {
100
126
  else {
101
127
  dayIdx = data.days.find(o => o.name === newDay);
102
128
  }
103
- newDate = data.days[dayIdx].date;
129
+ let newDate = data.days[dayIdx].date;
104
130
 
105
131
  let d = new Date(newDate);
106
132
  newTime = newTime.split(':');
@@ -111,7 +137,10 @@ window.conference.live = (function() {
111
137
  update();
112
138
  };
113
139
 
114
- let getTime = function (tConvert=time()) {
140
+ let getTime = function () {
141
+ // Return app time as string
142
+ let tConvert = time();
143
+
115
144
  let d = new Date(tConvert * 1000);
116
145
  let dStr = d.toISOString().slice(0,10);
117
146
  let h = d.getHours();
@@ -121,6 +150,7 @@ window.conference.live = (function() {
121
150
  };
122
151
 
123
152
  let timeUnit = function () {
153
+ // App time refresh rate
124
154
  if (demo) {
125
155
  return 0.1;
126
156
  }
@@ -130,6 +160,7 @@ window.conference.live = (function() {
130
160
  };
131
161
 
132
162
  let delayStart = function (startTime) {
163
+ // Seconds until given startTime occurs
133
164
  let tNow = time();
134
165
  let tUnit = timeUnit();
135
166
 
@@ -149,21 +180,25 @@ window.conference.live = (function() {
149
180
  };
150
181
 
151
182
  let toggleDemo = function () {
183
+ // Toggle app demo mode
152
184
  demo = !demo;
153
185
  resetTime();
154
186
  };
155
187
 
156
188
  let demoOn = function () {
189
+ // Return app demo status
157
190
  return demo;
158
191
  };
159
192
 
160
193
  let updateLive = function () {
194
+ // Update status all live elements in DOM
161
195
  let tNow = time();
162
196
  let liveShow = document.getElementsByClassName('live-show');
163
197
  let liveHide = document.getElementsByClassName('live-hide');
164
198
  let liveTime = document.getElementsByClassName('live-time');
165
199
  let livePast = document.getElementsByClassName('live-past');
166
200
 
201
+ // Show elements for a given period
167
202
  for (let i = 0; i < liveShow.length; i++) {
168
203
  let tStarts = liveShow[i].dataset.start.split(',');
169
204
  let tEnds = liveShow[i].dataset.end.split(',');
@@ -181,6 +216,7 @@ window.conference.live = (function() {
181
216
  }
182
217
  }
183
218
 
219
+ // Hide elements for a given period
184
220
  for (let i = 0; i < liveHide.length; i++) {
185
221
  let tStarts = liveHide[i].dataset.start.split(',');
186
222
  let tEnds = liveHide[i].dataset.end.split(',');
@@ -200,6 +236,7 @@ window.conference.live = (function() {
200
236
  }
201
237
  }
202
238
 
239
+ // Update duration string for given elements
203
240
  for (let i = 0; i < liveTime.length; i++) {
204
241
  let t = liveTime[i].dataset.time;
205
242
  if (typeof t == "undefined") {
@@ -259,6 +296,7 @@ window.conference.live = (function() {
259
296
  liveTime[i].innerHTML = tStr;
260
297
  }
261
298
 
299
+ // Disable elements for a given period
262
300
  for (let i = 0; i < livePast.length; i++) {
263
301
  let t = livePast[i].dataset.time;
264
302
  if (typeof t == "undefined") {
@@ -278,13 +316,14 @@ window.conference.live = (function() {
278
316
  }
279
317
  }
280
318
 
319
+ // Cancel timer after program is over
281
320
  if (tNow > confEnd && !demo) {
282
- // Cancel timer after program is over
283
321
  stopUpdateLive();
284
322
  }
285
323
  };
286
324
 
287
325
  let startUpdateLive = function () {
326
+ // Start update timer to update live elements in DOM
288
327
  stopUpdateLive();
289
328
  updateLive();
290
329
 
@@ -301,6 +340,7 @@ window.conference.live = (function() {
301
340
  };
302
341
 
303
342
  let stopUpdateLive = function () {
343
+ // stopUpdate update timer to update live elements in DOM
304
344
  if (typeof liveTimer !== "undefined") {
305
345
  clearInterval(liveTimer);
306
346
  }
@@ -312,9 +352,9 @@ window.conference.live = (function() {
312
352
  let streamExtend = {{ site.conference.live.streaming.time_extend | default: 5 }}; // in minutes
313
353
 
314
354
  let streamModal;
315
- let data;
316
355
 
317
356
  let getRoom = function (roomName) {
357
+ // Return room object for given room name
318
358
  if (roomName in data.rooms) {
319
359
  return data.rooms[roomName];
320
360
  }
@@ -324,6 +364,7 @@ window.conference.live = (function() {
324
364
  };
325
365
 
326
366
  let getNextTalk = function (roomName) {
367
+ // Get talk object for next talk in given room
327
368
  let timeNow = time();
328
369
  let talksHere = data.talks[roomName];
329
370
 
@@ -340,6 +381,7 @@ window.conference.live = (function() {
340
381
  };
341
382
 
342
383
  let getNextPause = function (roomName) {
384
+ // Get time object for next pause in given room
343
385
  let timeNow = time();
344
386
  let talksHere = data.talks[roomName];
345
387
 
@@ -358,20 +400,24 @@ window.conference.live = (function() {
358
400
  return false;
359
401
  };
360
402
 
361
- let setStreamContent = function (content) {
403
+ let setStreamIframeContent = function (content) {
404
+ // Set stream modal iframe to show given text
362
405
  streamModal.find('iframe').attr('src', '');
363
406
  streamModal.find('iframe').addClass('d-none');
364
407
  streamModal.find('#stream-placeholder > div').text(content);
365
408
  streamModal.find('#stream-placeholder').addClass('d-flex');
366
409
  };
367
410
 
368
- let setStreamSrc = function (href) {
411
+ let setStreamIframeSrc = function (href) {
412
+ // Set stream modal iframe to show given URL
369
413
  streamModal.find('iframe').attr('src', href);
370
414
  streamModal.find('#stream-placeholder').addClass('d-none').removeClass('d-flex');
371
415
  streamModal.find('iframe').removeClass('d-none');
372
416
  };
373
417
 
374
418
  let setStreamVideo = function (roomName) {
419
+ // Update stream modal iframe:
420
+ // Show stream with start/pause/end message (for given room) and keep updated
375
421
  let timeNow = time();
376
422
 
377
423
  let talksHere = data.talks[roomName];
@@ -384,7 +430,7 @@ window.conference.live = (function() {
384
430
 
385
431
  // Conference not yet started
386
432
  if (timeNow < roomStart - streamPrepend*60) {
387
- setStreamContent('{{ site.data.lang[site.conference.lang].live.pre_stream | default: "Live stream has not started yet." }}');
433
+ setStreamIframeContent('{{ site.data.lang[site.conference.lang].live.pre_stream | default: "Live stream has not started yet." }}');
388
434
 
389
435
  if (!freezeTime) {
390
436
  streamVideoTimer = setTimeout(setStreamVideo, delayStart(roomStart - streamPrepend*60) * 1000, roomName);
@@ -393,7 +439,7 @@ window.conference.live = (function() {
393
439
 
394
440
  // Conference is over
395
441
  else if (timeNow > roomEnd + streamExtend*60) {
396
- setStreamContent('{{ site.data.lang[site.conference.lang].live.post_stream | default: "Live stream has ended." }}');
442
+ setStreamIframeContent('{{ site.data.lang[site.conference.lang].live.post_stream | default: "Live stream has ended." }}');
397
443
 
398
444
  if (!freezeTime && demo) {
399
445
  streamVideoTimer = setTimeout(setStreamVideo, delayStart(roomEnd - streamPrepend*60) * 1000, roomName);
@@ -406,7 +452,7 @@ window.conference.live = (function() {
406
452
 
407
453
  // Currently stream is paused
408
454
  if (pauseNext && timeNow >= pauseNext.start + streamExtend*60 && timeNow <= pauseNext.end - streamPrepend*60) {
409
- setStreamContent('{{ site.data.lang[site.conference.lang].live.pause_stream | default: "Live stream is currently paused." }}');
455
+ setStreamIframeContent('{{ site.data.lang[site.conference.lang].live.pause_stream | default: "Live stream is currently paused." }}');
410
456
 
411
457
  if (!freezeTime) {
412
458
  streamVideoTimer = setTimeout(setStreamVideo, delayStart(pauseNext.end - streamPrepend*60) * 1000, roomName);
@@ -415,7 +461,7 @@ window.conference.live = (function() {
415
461
  // Currently a talk is active
416
462
  else {
417
463
  let room = getRoom(roomName);
418
- setStreamSrc(room.href);
464
+ setStreamIframeSrc(room.href);
419
465
 
420
466
  if (!freezeTime) {
421
467
  if (pauseNext) {
@@ -430,6 +476,8 @@ window.conference.live = (function() {
430
476
  };
431
477
 
432
478
  let setStreamInfo = function (roomName) {
479
+ // Update stream modal info bar:
480
+ // Show next talk and speaker (for given room) and keep updated
433
481
  let timeNow = time();
434
482
  let talkNext = getNextTalk(roomName);
435
483
 
@@ -484,6 +532,7 @@ window.conference.live = (function() {
484
532
  };
485
533
 
486
534
  let setStream = function (roomName) {
535
+ // Update stream modal (iframe and info bar) for given room
487
536
  streamModal.find('.modal-footer .btn').removeClass('active');
488
537
  streamModal.find('#stream-select').val(0);
489
538
 
@@ -499,6 +548,7 @@ window.conference.live = (function() {
499
548
  };
500
549
 
501
550
  let updateStream = function () {
551
+ // Update stream modal for currently active room button
502
552
  if (streamModal.hasClass('show')) {
503
553
  let activeButton = streamModal.find('.modal-footer .btn.active');
504
554
  let roomName = activeButton.data('room');
@@ -510,6 +560,7 @@ window.conference.live = (function() {
510
560
  };
511
561
 
512
562
  let stopUpdateStream = function () {
563
+ // Stop stream modal update timer
513
564
  if (typeof streamVideoTimer !== "undefined") {
514
565
  clearInterval(streamVideoTimer);
515
566
  }
@@ -518,13 +569,15 @@ window.conference.live = (function() {
518
569
  }
519
570
  };
520
571
 
521
- let hideModal = function (event) {
572
+ let hideModal = function () {
573
+ // Close stream modal
522
574
  streamModal.find('iframe').attr('src', '');
523
575
  streamModal.find('.modal-footer .btn').removeClass('active');
524
576
  streamModal.find('#stream-select').selectedIndex = -1;
525
577
  };
526
578
 
527
579
  let setupStream = function () {
580
+ // Setup events when modal opens/closes
528
581
  streamModal = $('#stream-modal');
529
582
 
530
583
  // configure modal opening buttons
@@ -533,8 +586,8 @@ window.conference.live = (function() {
533
586
  let roomName = button.data('room');
534
587
  setStream(roomName);
535
588
  });
536
- streamModal.on('hide.bs.modal', function (event) {
537
- hideModal(event);
589
+ streamModal.on('hide.bs.modal', function () {
590
+ hideModal();
538
591
  });
539
592
 
540
593
  // configure room selection buttons in modal
@@ -552,14 +605,10 @@ window.conference.live = (function() {
552
605
  let roomName = $(this).children('option:selected').text();
553
606
  setStream(roomName);
554
607
  });
555
-
556
- // load data
557
- $.getJSON('{{ site.baseurl }}/assets/js/data.json', function(json) {
558
- data = json;
559
- });
560
608
  };
561
609
 
562
610
  let setup = function () {
611
+ loadData();
563
612
  startUpdateLive();
564
613
  setupStream();
565
614
  };
@@ -582,6 +631,7 @@ window.conference.live = (function() {
582
631
  {%- else -%}
583
632
 
584
633
  let setup = function () {
634
+ loadData();
585
635
  startUpdateLive();
586
636
  };
587
637
 
@@ -601,6 +651,7 @@ window.conference.live = (function() {
601
651
 
602
652
  return {
603
653
  init: setup,
654
+ getData: getData,
604
655
 
605
656
  pauseTime: pauseTime,
606
657
  continueTime: continueTime,
@@ -24,7 +24,7 @@ window.conference.mapConfig = (function() {
24
24
  };
25
25
 
26
26
  let init = function () {
27
- elId = 'map';
27
+ let elId = 'map';
28
28
 
29
29
  if (document.getElementById(elId)) {
30
30
  setup(elId);
@@ -51,7 +51,7 @@ window.conference.modal = (function () {
51
51
  }
52
52
  };
53
53
 
54
- let hide = function (el, event) {
54
+ let hide = function (el) {
55
55
  let modal = $(el);
56
56
 
57
57
  modal.find('.modal-title h3').text('');
@@ -61,13 +61,13 @@ window.conference.modal = (function () {
61
61
  };
62
62
 
63
63
  let init = function() {
64
- elSel = '#link-modal';
64
+ let elSel = '#link-modal';
65
65
 
66
66
  $(elSel).on('show.bs.modal', function (event) {
67
67
  show(this, event);
68
68
  });
69
- $(elSel).on('hide.bs.modal', function (event) {
70
- hide(this, event);
69
+ $(elSel).on('hide.bs.modal', function () {
70
+ hide(this);
71
71
  });
72
72
  };
73
73
 
@@ -34,7 +34,7 @@ window.conference.program = (function() {
34
34
  }
35
35
 
36
36
  // Add current selected day as hash to URL while keeping current scrolling position
37
- $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
37
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function () {
38
38
  updateHash(this.hash);
39
39
  });
40
40
  }
@@ -29,7 +29,7 @@ function (exports) {
29
29
  var elems = document.getElementsByClassName('syncscroll');
30
30
  var i, j, el, found, name;
31
31
  for (name in names) {
32
- if (names.hasOwnProperty(name)) {
32
+ if (Object.prototype.hasOwnProperty.call(names, name)) {
33
33
  for (i = 0; i < names[name].length; i++) {
34
34
  names[name][i].removeEventListener(
35
35
  'scroll', names[name][i].syn, 0
@@ -4,7 +4,7 @@
4
4
 
5
5
  <div class="modal-header">
6
6
  <h5 class="modal-title">
7
- {{ site.data.lang[site.conference.lang].live.streaming | default: "Live Stream" }}
7
+ {{ site.data.lang[site.conference.lang].live.stream | default: "Live Stream" }}
8
8
  </h5>
9
9
  <button type="button" class="close" data-dismiss="modal" aria-label="Close">
10
10
  <span aria-hidden="true">&times;</span>
@@ -41,7 +41,18 @@
41
41
 
42
42
  <li class="nav-item live-show d-none" data-start="{{ live_starts }}" data-end="{{ live_ends }}">
43
43
  {%- if site.conference.live.streaming %}
44
- <a class="nav-link" title="{% if link.name %}{{ link.name }}{% else %}{{ site.data.lang[site.conference.lang].live.streaming | default: "Live Stream" }}{% endif %}" data-toggle="modal" data-target="#stream-modal" data-room="" href="#">
44
+ <a class="nav-link" title="
45
+ {%- if link.name -%}
46
+ {{- link.name -}}
47
+ {%- else -%}
48
+ {{- site.data.lang[site.conference.lang].live.stream | default: "Live Stream" -}}
49
+ {%- endif -%}
50
+ " {% if site.conference.live.streaming.external -%}
51
+ href="{{ site.conference.live.streaming.external }}"
52
+ {%- else -%}
53
+ data-toggle="modal" data-target="#stream-modal" data-room="{{ r.name }}" href="#"
54
+ {%- endif -%}
55
+ >
45
56
  {%- else %}
46
57
  {%- assign link_styleclass = "nav-link" -%}
47
58
  {%- include partials/get_link.html %}
@@ -2,7 +2,11 @@
2
2
  {%- include partials/get_talk_timestamp.html -%}
3
3
 
4
4
  {%- if site.conference.live.streaming -%}
5
- <a title="{{ link.name }}" data-toggle="modal" data-target="#stream-modal" data-room="{{ r.name }}" href="#"
5
+ <a title="{{ link.name }}" {% if site.conference.live.streaming.external -%}
6
+ href="{{ site.conference.live.streaming.external }}"
7
+ {%- else -%}
8
+ data-toggle="modal" data-target="#stream-modal" data-room="{{ r.name }}" href="#"
9
+ {%- endif -%}
6
10
  {%- else -%}
7
11
  <span
8
12
  {%- endif %} class="live-show live-button badge badge-dark font-weight-normal text-center d-none {{ live_button_styleclass }}" data-start="{{ timestamp_start }}" data-end="{{ timestamp_end }}">
data/_layouts/home.html CHANGED
@@ -23,11 +23,12 @@
23
23
 
24
24
  {% if site.conference.main.links %}
25
25
  <div class="lead d-print-none">
26
+ {% assign btn_default = 'btn btn-outline-primary btn-lg mt-2 ml-1' %}
26
27
  {% for link in site.conference.main.links %}
27
28
 
28
29
  {% if link.menu %}
29
30
  <div class="dropdown d-inline">
30
- <a class="btn btn-outline-primary btn-lg mt-2 dropdown-toggle" href="#" role="button" id="main-dropdown{{ forloop.index0 }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
31
+ <a class="{{ btn_default }} dropdown-toggle" href="#" role="button" id="main-dropdown{{ forloop.index0 }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
31
32
  {{ link.name }}
32
33
  </a>
33
34
  <div class="dropdown-menu" aria-labelledby="main-dropdown{{ forloop.index0 }}">
@@ -48,20 +49,20 @@
48
49
  {%- if link.name -%}
49
50
  {%- assign link_name = link.name -%}
50
51
  {%- else -%}
51
- {%- assign link_name = site.data.lang[site.conference.lang].live.streaming | default: "Live Stream" -%}
52
+ {%- assign link_name = site.data.lang[site.conference.lang].live.stream | default: "Live Stream" -%}
52
53
  {%- endif -%}
53
54
 
54
55
  {%- if link.name_inactive -%}
55
- <span class="live-hide btn btn-outline-primary btn-lg mt-2 disabled" data-start="{{ live_starts }}" data-end="{{ live_ends }}">
56
+ <span class="live-hide {{ btn_default }} disabled" data-start="{{ live_starts }}" data-end="{{ live_ends }}">
56
57
  {{ link.name_inactive }}
57
58
  </span>
58
59
  {%- endif -%}
59
60
 
60
61
  <span class="live-show d-none" data-start="{{ live_starts }}" data-end="{{ live_ends }}">
61
62
  {% if site.conference.live.streaming %}
62
- <a class="btn btn-outline-primary btn-lg mt-2" title="{{ link_name }}" data-toggle="modal" data-target="#stream-modal" data-room="" href="#">
63
+ <a class="{{ btn_default }}" title="{{ link_name }}" data-toggle="modal" data-target="#stream-modal" data-room="" href="#">
63
64
  {% else %}
64
- {% assign link_styleclass = "btn btn-outline-primary btn-lg mt-2" %}
65
+ {% assign link_styleclass = "{{ btn_default }}" %}
65
66
  {% include partials/get_link.html %}
66
67
  {{ link_tag }}
67
68
  {% endif %}
@@ -71,7 +72,7 @@
71
72
  </span>
72
73
 
73
74
  {% else %}
74
- {% assign link_styleclass = "btn btn-outline-primary btn-lg mt-2" %}
75
+ {% assign link_styleclass = btn_default %}
75
76
  {% include partials/get_link.html %}
76
77
  {{ link_tag }}
77
78
  {{ link.name }}
@@ -30,11 +30,11 @@
30
30
  {%- endif %}
31
31
 
32
32
  <div class="sticky-top syncscroll overflow-hidden" name="sync-table">
33
- <table class="table mb-0">
33
+ <table class="table mb-0 mx-auto">
34
34
  <thead>
35
35
  <tr>
36
- <th scope="col" class="text-right">#<span class="invisible">I0</span></th>
37
- <th class="p-0" scope="col"></th>
36
+ <th scope="col" class="col-title text-right">#<span class="invisible">I0</span></th>
37
+ <th class="col-space p-0" scope="col"></th>
38
38
  {%- assign nbr_rooms = d.rooms | size -%}
39
39
  {%- for r in d.rooms -%}
40
40
  {%- assign room = site.rooms | where: 'name', r.name | first %}
@@ -48,7 +48,7 @@
48
48
  {%- endif -%}
49
49
  </th>
50
50
  {%- unless forloop.last %}
51
- <th class="p-0" scope="col"></th>
51
+ <th class="col-space p-0" scope="col"></th>
52
52
  {%- endunless -%}
53
53
  {%- endfor %}
54
54
  </tr>
@@ -57,7 +57,7 @@
57
57
  </div>
58
58
 
59
59
  <div class="syncscroll overflow-y-hidden" name="sync-table">
60
- <table class="table">
60
+ <table class="table mx-auto">
61
61
  <tbody>
62
62
  {%- include partials/get_day_time.html -%}
63
63
 
@@ -85,17 +85,17 @@
85
85
  <tr>
86
86
 
87
87
  {%- if current_min == 0 -%}
88
- <th scope="row" class="text-right" style="z-index: {{ z-index-max }}">
88
+ <th scope="row" class="col-title text-right" style="z-index: {{ z-index-max }}">
89
89
  {{- current_time -}}
90
90
  </th>
91
91
  {%- elsif site.conference.program.show_alltimes -%}
92
- <th scope="row" class="text-right text-muted font-weight-normal" style="z-index: {{ z-index-max }}">
92
+ <th scope="row" class="col-title text-right text-muted font-weight-normal" style="z-index: {{ z-index-max }}">
93
93
  :{{ current_min }}
94
94
  </th>
95
95
  {%- else -%}
96
- <th scope="row" style="z-index: {{ z-index-max }}"></th>
96
+ <th scope="row" class="col-title" style="z-index: {{ z-index-max }}"></th>
97
97
  {%- endif %}
98
- <td class="p-0"></td>
98
+ <td class="col-space p-0"></td>
99
99
 
100
100
  {%- for r in d.rooms -%}
101
101
  {%- assign room = site.rooms | where: 'name', r.name | first -%}
@@ -135,7 +135,7 @@
135
135
 
136
136
  {%- assign talk_nbr_steps = talk_duration_min | divided_by: site.conference.program.time_steps -%}
137
137
  {%- include partials/get_main_category.html -%}
138
- <td rowspan="{{ talk_nbr_steps }}" class="alert alert-{{ main_cat_color }} shadow-sm" style="z-index: {{ z-index-max | minus: i }}">
138
+ <td rowspan="{{ talk_nbr_steps }}" class="alert alert-{{ main_cat_color }} shadow-sm overflow-hidden" style="z-index: {{ z-index-max | minus: i }}">
139
139
 
140
140
  {%- assign live_button_styleclass = "mb-2" %}
141
141
  {%- include partials/show_live_button.html %}
@@ -161,7 +161,7 @@
161
161
  {%- endunless -%}
162
162
 
163
163
  {%- if forloop.last != true %}
164
- <td class="p-0"></td>
164
+ <td class="col-space p-0"></td>
165
165
  {%- endif -%}
166
166
 
167
167
  {%- endfor %}
@@ -0,0 +1,42 @@
1
+ {% include partials/header.html %}
2
+
3
+ <h1 class="display-5 mb-4">
4
+ {% if page.title %}
5
+ {{ page.title }}
6
+ {% else %}
7
+ {{ site.data.lang[site.conference.lang].live.stream | default: "Live Streams" }}
8
+ {% endif %}
9
+ </h1>
10
+
11
+ {{ content }}
12
+
13
+ {%- assign nbr_streams = 0 -%}
14
+ {%- for room in site.rooms -%}
15
+ {%- if room.live -%}
16
+ {%- assign mod_nbr_streams = nbr_streams | modulo: 2 -%}
17
+ {%- if mod_nbr_streams == 0 %}
18
+ <div class="row">
19
+ {%- endif %}
20
+
21
+ <div class="col-md">
22
+ <h3>{{ room.name }}</h3>
23
+ <div class="embed-responsive embed-responsive-16by9">
24
+ <iframe class="embed-responsive-item" src="{{ room.live }}" allowfullscreen></iframe>
25
+ </div>
26
+ </div>
27
+
28
+ {%- if mod_nbr_streams == 1 %}
29
+ </div>
30
+ {%- endif -%}
31
+
32
+ {%- assign nbr_streams = nbr_streams | plus: 1 -%}
33
+ {%- endif -%}
34
+ {%- endfor %}
35
+
36
+ {% assign mod_nbr_streams = nbr_streams | modulo: 2 %}
37
+ {%- if mod_nbr_streams == 1 %}
38
+ <div class="col-md"></div>
39
+ </div>
40
+ {%- endif %}
41
+
42
+ {% include partials/footer.html %}
@@ -79,6 +79,12 @@ ul.btn-group {
79
79
 
80
80
  // General
81
81
 
82
+ // Keep images in container
83
+ main.container img {
84
+ max-width: 100%;
85
+ height: auto;
86
+ }
87
+
82
88
  // No bottom margin on info-bar
83
89
  .alert > p:last-of-type {
84
90
  margin-bottom: 0;
@@ -130,22 +136,26 @@ ul.btn-group {
130
136
  // First row defines width for all columns
131
137
  table-layout: fixed;
132
138
 
133
- // Table width
134
- min-width: 100%;
139
+ // Columns define table width
140
+ width: auto;
135
141
 
136
142
  // Column widths
137
- tr {
143
+ th, td {
144
+ // Total available container width is 1110px
145
+
146
+ // Width of columns with content (default)
147
+ width: 245px;
148
+ min-width: 245px;
149
+
138
150
  // Spacing between columns
139
- > :nth-child(even) {
140
- width: 10px;
141
- }
142
- // Width of columns with content
143
- > :nth-child(odd) {
144
- width: 180px;
151
+ &.col-space {
152
+ width: 15px;
153
+ min-width: 15px;
145
154
  }
146
155
  // Width of first column containing timestamps
147
- > :nth-child(1) {
148
- width: 4.5em;
156
+ &.col-title {
157
+ width: 70px;
158
+ min-width: 70px;
149
159
  }
150
160
  }
151
161
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-theme-conference
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorenz Schmid
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-08 00:00:00.000000000 Z
11
+ date: 2021-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -108,6 +108,7 @@ files:
108
108
  - _layouts/room.html
109
109
  - _layouts/speaker-overview.html
110
110
  - _layouts/speaker.html
111
+ - _layouts/stream-overview.html
111
112
  - _layouts/talk-overview.html
112
113
  - _layouts/talk.html
113
114
  - _sass/bootstrap/_alert.scss
@@ -278,7 +279,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
278
279
  - !ruby/object:Gem::Version
279
280
  version: '0'
280
281
  requirements: []
281
- rubygems_version: 3.1.4
282
+ rubygems_version: 3.2.3
282
283
  signing_key:
283
284
  specification_version: 4
284
285
  summary: Jekyll template for a conference website containing program, speaker, talks