Skip to content

Commit a560499

Browse files
Add timezone selector to upcoming meetings page. Separate general timezone handling from parts only relevant to main agenda page. Speed up agenda timezone javascript tests. Fixes ietf-tools#3184. Commit ready for merge.
- Legacy-Id: 18970
1 parent b08110b commit a560499

7 files changed

Lines changed: 749 additions & 387 deletions

File tree

ietf/meeting/tests_js.py

Lines changed: 224 additions & 43 deletions
Large diffs are not rendered by default.

ietf/meeting/views.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,7 +3363,7 @@ def upcoming(request):
33633363
# Get ietf meetings starting 7 days ago, and interim meetings starting today
33643364
ietf_meetings = Meeting.objects.filter(type_id='ietf', date__gte=today-datetime.timedelta(days=7))
33653365
for m in ietf_meetings:
3366-
m.end = m.date+datetime.timedelta(days=m.days)
3366+
m.end = m.date + datetime.timedelta(days=m.days-1) # subtract 1 to avoid counting an extra day
33673367

33683368
interim_sessions = add_event_info_to_session_qs(
33693369
Session.objects.filter(
@@ -3411,13 +3411,11 @@ def upcoming(request):
34113411

34123412
for o in entries:
34133413
if isinstance(o, Meeting):
3414-
o.start_timestamp = int(pytz.utc.localize(datetime.datetime.combine(o.date, datetime.datetime.min.time())).timestamp())
3415-
o.end_timestamp = int(pytz.utc.localize(datetime.datetime.combine(o.end, datetime.datetime.max.time())).timestamp())
3414+
o.start_timestamp = int(pytz.utc.localize(datetime.datetime.combine(o.date, datetime.time.min)).timestamp())
3415+
o.end_timestamp = int(pytz.utc.localize(datetime.datetime.combine(o.end, datetime.time.max)).timestamp())
34163416
else:
3417-
o.start_timestamp = int(o.official_timeslotassignment().
3418-
timeslot.utc_start_time().timestamp());
3419-
o.end_timestamp = int(o.official_timeslotassignment().
3420-
timeslot.utc_end_time().timestamp());
3417+
o.start_timestamp = int(o.official_timeslotassignment().timeslot.utc_start_time().timestamp())
3418+
o.end_timestamp = int(o.official_timeslotassignment().timeslot.utc_end_time().timestamp())
34213419

34223420
# add menu entries
34233421
menu_entries = get_interim_menu_entries(request)

ietf/static/ietf/js/agenda/agenda_filter.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ var agenda_filter_for_testing; // methods to be accessed for automated testing
232232
* button UI. Do not call if you only want to use the parameter parsing routines.
233233
*/
234234
function enable () {
235+
// ready handler fires immediately if document is already "ready"
235236
$(document).ready(function () {
236237
register_handlers();
237238
update_view();
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
// Copyright The IETF Trust 2021, All Rights Reserved
2+
3+
/*
4+
Timezone support specific to the agenda page
5+
6+
To properly handle timezones other than local, needs a method to retrieve
7+
the current timezone. Set this by passing a method taking no parameters and
8+
returning the current timezone to the set_current_tz_cb() method.
9+
This should be done before calling anything else in the file.
10+
*/
11+
12+
var meeting_timezone;
13+
var local_timezone = moment.tz.guess();
14+
15+
// get_current_tz_cb must be overwritten using set_current_tz_cb
16+
var get_current_tz_cb = function () {
17+
throw new Error('Tried to get current timezone before callback registered. Use set_current_tz_cb().')
18+
};
19+
20+
// Initialize moments
21+
function initialize_moments() {
22+
var times=$('span.time')
23+
$.each(times, function(i, item) {
24+
item.start_ts = moment.unix(this.getAttribute("data-start-time")).utc();
25+
item.end_ts = moment.unix(this.getAttribute("data-end-time")).utc();
26+
if (this.hasAttribute("weekday")) {
27+
item.format=2;
28+
} else {
29+
item.format=1;
30+
}
31+
if (this.hasAttribute("format")) {
32+
item.format = +this.getAttribute("format");
33+
}
34+
});
35+
var times=$('[data-slot-start-ts]')
36+
$.each(times, function(i, item) {
37+
item.slot_start_ts = moment.unix(this.getAttribute("data-slot-start-ts")).utc();
38+
item.slot_end_ts = moment.unix(this.getAttribute("data-slot-end-ts")).utc();
39+
});
40+
}
41+
42+
function format_time(t, tz, fmt) {
43+
var out;
44+
var mtz = meeting_timezone;
45+
if (mtz == "") {
46+
mtz = "UTC";
47+
}
48+
49+
switch (fmt) {
50+
case 0:
51+
out = t.tz(tz).format('dddd, ') + '<span class="hidden-xs">' +
52+
t.tz(tz).format('MMMM Do YYYY, ') + '</span>' +
53+
t.tz(tz).format('HH:mm') + '<span class="hidden-xs">' +
54+
t.tz(tz).format(' Z z') + '</span>';
55+
break;
56+
case 1:
57+
// Note, this code does not work if the meeting crosses the
58+
// year boundary.
59+
out = t.tz(tz).format("HH:mm");
60+
if (+t.tz(tz).dayOfYear() < +t.tz(mtz).dayOfYear()) {
61+
out = out + " (-1)";
62+
} else if (+t.tz(tz).dayOfYear() > +t.tz(mtz).dayOfYear()) {
63+
out = out + " (+1)";
64+
}
65+
break;
66+
case 2:
67+
out = t.tz(mtz).format("dddd, ").toUpperCase() +
68+
t.tz(tz).format("HH:mm");
69+
if (+t.tz(tz).dayOfYear() < +t.tz(mtz).dayOfYear()) {
70+
out = out + " (-1)";
71+
} else if (+t.tz(tz).dayOfYear() > +t.tz(mtz).dayOfYear()) {
72+
out = out + " (+1)";
73+
}
74+
break;
75+
case 3:
76+
out = t.utc().format("YYYY-MM-DD");
77+
break;
78+
case 4:
79+
out = t.tz(tz).format("YYYY-MM-DD HH:mm");
80+
break;
81+
case 5:
82+
out = t.tz(tz).format("HH:mm");
83+
break;
84+
}
85+
return out;
86+
}
87+
88+
89+
// Format tooltip notice
90+
function format_tooltip_notice(start, end) {
91+
var notice = "";
92+
93+
if (end.isBefore()) {
94+
notice = "Event ended " + end.fromNow();
95+
} else if (start.isAfter()) {
96+
notice = "Event will start " + start.fromNow();
97+
} else {
98+
notice = "Event started " + start.fromNow() + " and will end " +
99+
end.fromNow();
100+
}
101+
return '<span class="tooltipnotice">' + notice + '</span>';
102+
}
103+
104+
// Format tooltip table
105+
function format_tooltip_table(start, end) {
106+
var current_timezone = get_current_tz_cb();
107+
var out = '<table><tr><th>Timezone</th><th>Start</th><th>End</th></tr>';
108+
if (meeting_timezone !== "") {
109+
out += '<tr><td class="timehead">Meeting timezone:</td><td>' +
110+
format_time(start, meeting_timezone, 0) + '</td><td>' +
111+
format_time(end, meeting_timezone, 0) + '</td></tr>';
112+
}
113+
out += '<tr><td class="timehead">Local timezone:</td><td>' +
114+
format_time(start, local_timezone, 0) + '</td><td>' +
115+
format_time(end, local_timezone, 0) + '</td></tr>';
116+
if (current_timezone !== 'UTC') {
117+
out += '<tr><td class="timehead">Selected Timezone:</td><td>' +
118+
format_time(start, current_timezone, 0) + '</td><td>' +
119+
format_time(end, current_timezone, 0) + '</td></tr>';
120+
}
121+
out += '<tr><td class="timehead">UTC:</td><td>' +
122+
format_time(start, 'UTC', 0) + '</td><td>' +
123+
format_time(end, 'UTC', 0) + '</td></tr>';
124+
out += '</table>' + format_tooltip_notice(start, end);
125+
return out;
126+
}
127+
128+
// Format tooltip for item
129+
function format_tooltip(start, end) {
130+
return '<span class="timetooltiptext">' +
131+
format_tooltip_table(start, end) +
132+
'</span>';
133+
}
134+
135+
// Add tooltips
136+
function add_tooltips() {
137+
$('span.time').each(function () {
138+
var tooltip = $(format_tooltip(this.start_ts, this.end_ts));
139+
tooltip[0].start_ts = this.start_ts;
140+
tooltip[0].end_ts = this.end_ts;
141+
tooltip[0].ustart_ts = moment(this.start_ts).add(-2, 'hours');
142+
tooltip[0].uend_ts = moment(this.end_ts).add(2, 'hours');
143+
$(this).parent().append(tooltip);
144+
});
145+
}
146+
147+
// Update times on the agenda based on the selected timezone
148+
function update_times(newtz) {
149+
$('span.current-tz').html(newtz);
150+
$('span.time').each(function () {
151+
if (this.format == 4) {
152+
var tz = this.start_ts.tz(newtz).format(" z");
153+
if (this.start_ts.tz(newtz).dayOfYear() ==
154+
this.end_ts.tz(newtz).dayOfYear()) {
155+
$(this).html(format_time(this.start_ts, newtz, this.format) +
156+
'-' + format_time(this.end_ts, newtz, 5) + tz);
157+
} else {
158+
$(this).html(format_time(this.start_ts, newtz, this.format) +
159+
'-' +
160+
format_time(this.end_ts, newtz, this.format) + tz);
161+
}
162+
} else {
163+
$(this).html(format_time(this.start_ts, newtz, this.format) + '-' +
164+
format_time(this.end_ts, newtz, this.format));
165+
}
166+
});
167+
update_tooltips_all();
168+
update_clock();
169+
}
170+
171+
// Highlight ongoing based on the current time
172+
function highlight_ongoing() {
173+
$("div#now").remove("#now");
174+
$('.ongoing').removeClass("ongoing");
175+
var agenda_rows=$('[data-slot-start-ts]')
176+
agenda_rows = agenda_rows.filter(function() {
177+
return moment().isBetween(this.slot_start_ts, this.slot_end_ts);
178+
});
179+
agenda_rows.addClass("ongoing");
180+
agenda_rows.first().children("th, td").
181+
prepend($('<div id="now" class="anchor-target"></div>'));
182+
}
183+
184+
// Update tooltips
185+
function update_tooltips() {
186+
var tooltips=$('.timetooltiptext');
187+
tooltips.filter(function() {
188+
return moment().isBetween(this.ustart_ts, this.uend_ts);
189+
}).each(function () {
190+
$(this).html(format_tooltip_table(this.start_ts, this.end_ts));
191+
});
192+
}
193+
194+
// Update all tooltips
195+
function update_tooltips_all() {
196+
var tooltips=$('.timetooltiptext');
197+
tooltips.each(function () {
198+
$(this).html(format_tooltip_table(this.start_ts, this.end_ts));
199+
});
200+
}
201+
202+
// Update clock
203+
function update_clock() {
204+
$('#current-time').html(format_time(moment(), get_current_tz_cb(), 0));
205+
}
206+
207+
$.urlParam = function(name) {
208+
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
209+
if (results == null) {
210+
return null;
211+
} else {
212+
return results[1] || 0;
213+
}
214+
}
215+
216+
function init_timers() {
217+
var fast_timer = 60000 / (speedup > 600 ? 600 : speedup);
218+
update_clock();
219+
highlight_ongoing();
220+
setInterval(function() { update_clock(); }, fast_timer);
221+
setInterval(function() { highlight_ongoing(); }, fast_timer);
222+
setInterval(function() { update_tooltips(); }, fast_timer);
223+
setInterval(function() { update_tooltips_all(); }, 3600000 / speedup);
224+
}
225+
226+
// set method used to find current time zone
227+
function set_current_tz_cb(fn) {
228+
get_current_tz_cb = fn;
229+
}

0 commit comments

Comments
 (0)