-
Notifications
You must be signed in to change notification settings - Fork 7
/
main.js
189 lines (166 loc) · 5.07 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
---
---
$(function() {
deadlineByConf = {};
{% for conf in site.data.conferences %}
{% assign conf_id = conf.name | append: conf.year | slugify %}
{% if conf.deadline == "TBA" %}
$('#{{ conf_id }} .timer').html("TBA");
$('#{{ conf_id }} .deadline-time').html("TBA");
deadlineByConf["{{ conf_id }}"] = null;
{% else %}
var rawDeadlines = {{ conf.deadline | jsonify }} || [];
if (rawDeadlines.constructor !== Array) {
rawDeadlines = [rawDeadlines];
}
var parsedDeadlines = [];
while (rawDeadlines.length > 0) {
var rawDeadline = rawDeadlines.pop();
// check if date is template
if (rawDeadline.indexOf('%y') >= 0) {
year = parseInt(moment().year());
rawDeadlines.push(rawDeadline.replace('%y', year));
rawDeadlines.push(rawDeadline.replace('%y', year + 1));
} else {
// adjust date according to deadline timezone
{% if conf.timezone %}
var deadline = moment.tz(rawDeadline, "{{ conf.timezone }}");
{% else %}
var deadline = moment.tz(rawDeadline, "Etc/GMT+12"); // Anywhere on Earth
{% endif %}
// post-process date
if (deadline.minutes() === 0) {
deadline.subtract(1, 'seconds');
}
if (deadline.minutes() === 59) {
deadline.seconds(59);
}
parsedDeadlines.push(deadline);
}
}
// check which deadline is closest
var confDeadline = parsedDeadlines[0];
var today = moment();
for (var i = 1; i < parsedDeadlines.length; i++) {
deadlineCandidate = parsedDeadlines[i];
if ((today.diff(deadlineCandidate) < 0 && today.diff(deadlineCandidate) > today.diff(confDeadline))) {
confDeadline = deadlineCandidate;
}
}
// render countdown timer
if (confDeadline) {
function make_update_countdown_fn(confDeadline) {
return function(event) {
diff = moment() - confDeadline
if (diff <= 0) {
$(this).html(event.strftime('%D days %Hh %Mm %Ss'));
} else {
$(this).html(confDeadline.fromNow());
}
}
}
$('#{{ conf_id }} .timer').countdown(confDeadline.toDate(), make_update_countdown_fn(confDeadline));
// check if date has passed, add 'past' class to it
if (moment() - confDeadline > 0) {
$('#{{ conf_id }}').addClass('past');
}
$('#{{ conf_id }} .deadline-time').html(confDeadline.local().format('D MMM YYYY, h:mm:ss a'));
deadlineByConf["{{ conf_id }}"] = confDeadline;
}
{% endif %}
{% endfor %}
// Reorder list
confs = $('.conf');
confs.detach().sort(function(a, b) {
// Target sorting:
// dates after today in ascending order
// null values
// dates before today in descending order
const aDate = deadlineByConf[a.id];
const bDate = deadlineByConf[b.id];
if (aDate === bDate || aDate?.isSame(bDate)) {
return 0;
}
const today = moment();
// Sort null values to the middle
if (aDate == null) {
if (today.isBefore(bDate)) {
return +1;
}
return -1;
}
if (bDate == null) {
if (today.isBefore(aDate)) {
return -1;
}
return +1;
}
// Effectively calculates (today - other)
const tDiffA = today.diff(aDate);
const tDiffB = today.diff(bDate);
// Sort remaining values ascending if upcoming, descending otherwise
// Both after today (upcoming): ascending
if (tDiffA <= 0 && tDiffB <= 0) {
return aDate.diff(bDate);
}
// Both before today (past): descending
if (tDiffA > 0 && tDiffB > 0) {
return bDate.diff(aDate);
}
// Remaining cases: (a < today < b) and (b < today < a)
// Here, we sort descending to move upcoming dates to the front.
return bDate.diff(aDate);
});
$('.conf-container').append(confs);
// Set checkboxes
var conf_type_data = {{ site.data.types | jsonify }};
var all_tags = [];
var toggle_status = {};
for (var i = 0; i < conf_type_data.length; i++) {
all_tags[i] = conf_type_data[i]['tag'];
toggle_status[all_tags[i]] = false;
}
var tags = store.get('{{ site.domain }}');
if (tags === undefined) {
tags = all_tags;
}
for (var i = 0; i < tags.length; i++) {
$('#' + tags[i] + '-checkbox').prop('checked', true);
toggle_status[tags[i]] = true;
}
store.set('{{ site.domain }}', tags);
function update_conf_list() {
confs.each(function(i, conf) {
var conf = $(conf);
var show = false;
for (var i = 0; i < all_tags.length; i++) {
if(conf.hasClass(all_tags[i])) {
show = show | toggle_status[all_tags[i]];
}
}
if (show) {
conf.show();
} else {
conf.hide()
}
});
}
update_conf_list();
// Event handler on checkbox change
$('form :checkbox').change(function(e) {
var checked = $(this).is(':checked');
var tag = $(this).prop('id').slice(0, -9);
toggle_status[tag] = checked;
if (checked == true) {
if (tags.indexOf(tag) < 0)
tags.push(tag);
}
else {
var idx = tags.indexOf(tag);
if (idx >= 0)
tags.splice(idx, 1);
}
store.set('{{ site.domain }}', tags);
update_conf_list();
});
});