Skip to content

Commit 09809b8

Browse files
committed
Merged in [18689] from kivinen@iki.fi:
New version of the timezone support for agenda. Now the ongoing bars work. This also moves the javascript from the agenda.html to separate timezone.js file. This commit does not include the moment and moment-timezone javascript libraries that are needed to get this working, they need to be added to ietf/externals/static separately. - Legacy-Id: 18800 Note: SVN reference [18689] has been migrated to Git commit f18fe23
2 parents 159b8fe + f18fe23 commit 09809b8

7 files changed

Lines changed: 408 additions & 19 deletions

File tree

hold-for-merge

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- conf-mode -*-
22

3-
/personal/kivinen/7.22.1.dev0@18689 # Hold for revision based on timezone-aware code
3+
# Everyting below this line is OBE
44

55
/personal/rcross/7.19.1.dev0@18663
66
/personal/rcross/7.19.1.dev0@18662

ietf/meeting/helpers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ def preprocess_assignments_for_agenda(assignments_queryset, meeting, extra_prefe
238238
d.get_href(meeting=meeting)
239239
d.get_versionless_href(meeting=meeting)
240240

241+
a.start_timestamp = int(a.timeslot.utc_start_time().timestamp())
242+
a.end_timestamp = int(a.timeslot.utc_end_time().timestamp())
243+
241244
return assignments
242245

243246
def tag_assignments_with_filter_keywords(assignments):

ietf/meeting/views.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,7 @@ def agenda(request, num=None, name=None, base=None, ext=None, owner=None, utc=""
14581458
"filter_categories": filter_categories,
14591459
"non_area_keywords": [label.lower() for label in non_area_labels],
14601460
"now": datetime.datetime.now().astimezone(pytz.UTC),
1461+
"timezone": meeting.time_zone,
14611462
"is_current_meeting": is_current_meeting,
14621463
"use_codimd": True if meeting.date>=settings.MEETING_USES_CODIMD_DATE else False,
14631464
"cache_time": 150 if is_current_meeting else 3600,
@@ -3392,6 +3393,16 @@ def upcoming(request):
33923393
entries.extend(list(interim_sessions))
33933394
entries.sort(key = lambda o: pytz.utc.localize(datetime.datetime.combine(o.date, datetime.datetime.min.time())) if isinstance(o,Meeting) else o.official_timeslotassignment().timeslot.utc_start_time())
33943395

3396+
for o in entries:
3397+
if isinstance(o, Meeting):
3398+
o.start_timestamp = int(pytz.utc.localize(datetime.datetime.combine(o.date, datetime.datetime.min.time())).timestamp())
3399+
o.end_timestamp = int(pytz.utc.localize(datetime.datetime.combine(o.end, datetime.datetime.max.time())).timestamp())
3400+
else:
3401+
o.start_timestamp = int(o.official_timeslotassignment().
3402+
timeslot.utc_start_time().timestamp());
3403+
o.end_timestamp = int(o.official_timeslotassignment().
3404+
timeslot.utc_end_time().timestamp());
3405+
33953406
# add menu entries
33963407
menu_entries = get_interim_menu_entries(request)
33973408
selected_menu_entry = 'upcoming'

ietf/static/ietf/css/ietf.css

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,3 +1460,63 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container {
14601460
width: 10em;
14611461
}
14621462

1463+
.rightmarker, .leftmarker {
1464+
width: 3px;
1465+
padding-right: 0px !important;
1466+
padding-left: 0px !important;
1467+
}
1468+
.ongoing > td:first-child {
1469+
background-color: red !important;
1470+
}
1471+
1472+
.ongoing > td:last-child {
1473+
background-color: red !important;
1474+
}
1475+
1476+
.timetooltip {
1477+
position: relative;
1478+
}
1479+
1480+
.timetooltip .timetooltiptext {
1481+
visibility: hidden;
1482+
background-color: #eee;
1483+
color: #000;
1484+
text-align: left;
1485+
border-radius: 6px;
1486+
padding: 5px 5px;
1487+
position: absolute;
1488+
z-index: 110;
1489+
bottom: 125%;
1490+
left: 50%;
1491+
margin-left: -60px;
1492+
opacity: 0;
1493+
transition: opacity 0.3s;
1494+
width: 60em;
1495+
}
1496+
1497+
.reschedtimetooltip .timetooltiptext {
1498+
margin-left: -300px;
1499+
}
1500+
1501+
.timetooltiptext table tr td {
1502+
padding: 1px 5px;
1503+
}
1504+
1505+
.timetooltiptext table tr th {
1506+
text-align: center;
1507+
}
1508+
1509+
.timehead {
1510+
text-align: right;
1511+
font-weight: bold;
1512+
}
1513+
1514+
.timetooltip:hover .timetooltiptext {
1515+
visibility: visible;
1516+
opacity: 1;
1517+
}
1518+
1519+
#current-time {
1520+
display: inline-block;
1521+
}
1522+
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
// Initialize moments
2+
function initialize_moments() {
3+
var times=$('span.time')
4+
$.each(times, function(i, item) {
5+
item.start_ts = moment.unix(this.getAttribute("data-start-time")).utc();
6+
item.end_ts = moment.unix(this.getAttribute("data-end-time")).utc();
7+
if (this.hasAttribute("weekday")) {
8+
item.format=2;
9+
} else {
10+
item.format=1;
11+
}
12+
if (this.hasAttribute("format")) {
13+
item.format = +this.getAttribute("format");
14+
}
15+
});
16+
var times=$('[data-slot-start-ts]')
17+
$.each(times, function(i, item) {
18+
item.slot_start_ts = moment.unix(this.getAttribute("data-slot-start-ts")).utc();
19+
item.slot_end_ts = moment.unix(this.getAttribute("data-slot-end-ts")).utc();
20+
});
21+
}
22+
23+
// Initialize timezone system
24+
function timezone_init(current) {
25+
var tz_names = moment.tz.names();
26+
var select = $('#timezone_select');
27+
28+
$.each(tz_names, function(i, item) {
29+
if (current == item) {
30+
select.append($('<option/>', {
31+
selected: "selected", html: item, value: item }));
32+
} else {
33+
select.append($('<option/>', {
34+
html: item, value: item }));
35+
}
36+
});
37+
initialize_moments();
38+
select.change(function () {
39+
update_times(this.value);
40+
});
41+
update_times(current);
42+
add_tooltips();
43+
}
44+
45+
// Select which timezone is used, 0 = meeting, 1 = browser local, 2 = UTC
46+
function use_timezone (val) {
47+
switch (val) {
48+
case 0:
49+
tz = meeting_timezone;
50+
break;
51+
case 1:
52+
tz = local_timezone;
53+
break;
54+
default:
55+
tz = 'UTC';
56+
break;
57+
}
58+
$('#timezone_select').val(tz);
59+
update_times(tz);
60+
}
61+
62+
// Format time for item for timezone. Depending on the fmt
63+
// use different formats.
64+
// Formats: 0 = long format "Saturday, October 24th 2020, 13:52 +00:00 UTC"
65+
// 1 = Short format "13:52", "13:52 (-1)", or "13:52 (+1)"
66+
// 2 = Short format with weekday, "Friday, 13:52 (-1)"
67+
// 3 = Date only "2020-10-24"
68+
// 4 = Date and time "2020-10-24 13:52"
69+
// 5 = Time only "13:52".
70+
71+
function format_time(t, tz, fmt) {
72+
var out;
73+
var mtz = meeting_timezone;
74+
if (mtz == "") {
75+
mtz = "UTC";
76+
}
77+
78+
switch (fmt) {
79+
case 0:
80+
out = t.tz(tz).format('dddd, ') + '<span class="hidden-xs">' +
81+
t.tz(tz).format('MMMM Do YYYY, ') + '</span>' +
82+
t.tz(tz).format('HH:mm') + '<span class="hidden-xs">' +
83+
t.tz(tz).format(' Z z') + '</span>';
84+
break;
85+
case 1:
86+
// Note, this code does not work if the meeting crosses the
87+
// year boundary.
88+
out = t.tz(tz).format("HH:mm");
89+
if (+t.tz(tz).dayOfYear() < +t.tz(mtz).dayOfYear()) {
90+
out = out + " (-1)";
91+
} else if (+t.tz(tz).dayOfYear() > +t.tz(mtz).dayOfYear()) {
92+
out = out + " (+1)";
93+
}
94+
break;
95+
case 2:
96+
out = t.tz(mtz).format("dddd, ").toUpperCase() +
97+
t.tz(tz).format("HH:mm");
98+
if (+t.tz(tz).dayOfYear() < +t.tz(mtz).dayOfYear()) {
99+
out = out + " (-1)";
100+
} else if (+t.tz(tz).dayOfYear() > +t.tz(mtz).dayOfYear()) {
101+
out = out + " (+1)";
102+
}
103+
break;
104+
case 3:
105+
out = t.utc().format("YYYY-MM-DD");
106+
break;
107+
case 4:
108+
out = t.tz(tz).format("YYYY-MM-DD HH:mm");
109+
break;
110+
case 5:
111+
out = t.tz(tz).format("HH:mm");
112+
break;
113+
}
114+
return out;
115+
}
116+
117+
118+
// Format tooltip notice
119+
function format_tooltip_notice(start, end) {
120+
var notice = "";
121+
122+
if (end.isBefore()) {
123+
notice = "Event ended " + end.fromNow();
124+
} else if (start.isAfter()) {
125+
notice = "Event will start " + start.fromNow();
126+
} else {
127+
notice = "Event started " + start.fromNow() + " and will end " +
128+
end.fromNow();
129+
}
130+
return '<span class="tooltipnotice">' + notice + '</span>';
131+
}
132+
133+
// Format tooltip table
134+
function format_tooltip_table(start, end) {
135+
var out = '<table><tr><th>Timezone</th><th>Start</th><th>End</th></tr>';
136+
if (meeting_timezone != "") {
137+
out += '<tr><td class="timehead">Meeting timezone:</td><td>' +
138+
format_time(start, meeting_timezone, 0) + '</td><td>' +
139+
format_time(end, meeting_timezone, 0) + '</td></tr>';
140+
}
141+
out += '<tr><td class="timehead">Local timezone:</td><td>' +
142+
format_time(start, local_timezone, 0) + '</td><td>' +
143+
format_time(end, local_timezone, 0) + '</td></tr>';
144+
if (current_timezone != 'UTC') {
145+
out += '<tr><td class="timehead">Selected Timezone:</td><td>' +
146+
format_time(start, current_timezone, 0) + '</td><td>' +
147+
format_time(end, current_timezone, 0) + '</td></tr>';
148+
}
149+
out += '<tr><td class="timehead">UTC:</td><td>' +
150+
format_time(start, 'UTC', 0) + '</td><td>' +
151+
format_time(end, 'UTC', 0) + '</td></tr>';
152+
out += '</table>' + format_tooltip_notice(start, end);
153+
return out;
154+
}
155+
156+
// Format tooltip for item
157+
function format_tooltip(start, end) {
158+
return '<span class="timetooltiptext">' +
159+
format_tooltip_table(start, end) +
160+
'</span>';
161+
}
162+
163+
// Add tooltips
164+
function add_tooltips() {
165+
$('span.time').each(function () {
166+
var tooltip = $(format_tooltip(this.start_ts, this.end_ts));
167+
tooltip[0].start_ts = this.start_ts;
168+
tooltip[0].end_ts = this.end_ts;
169+
tooltip[0].ustart_ts = moment(this.start_ts).add(-2, 'hours');
170+
tooltip[0].uend_ts = moment(this.end_ts).add(2, 'hours');
171+
$(this).parent().append(tooltip);
172+
});
173+
}
174+
175+
// Update times on the agenda based on the selected timezone
176+
function update_times(newtz) {
177+
current_timezone = newtz;
178+
$('#title-timezone').html(newtz);
179+
$('span.time').each(function () {
180+
if (this.format == 4) {
181+
var tz = this.start_ts.tz(newtz).format(" z");
182+
if (this.start_ts.tz(newtz).dayOfYear() ==
183+
this.end_ts.tz(newtz).dayOfYear()) {
184+
$(this).html(format_time(this.start_ts, newtz, this.format) +
185+
'-' + format_time(this.end_ts, newtz, 5) + tz);
186+
} else {
187+
$(this).html(format_time(this.start_ts, newtz, this.format) +
188+
'-' +
189+
format_time(this.end_ts, newtz, this.format) + tz);
190+
}
191+
} else {
192+
$(this).html(format_time(this.start_ts, newtz, this.format) + '-' +
193+
format_time(this.end_ts, newtz, this.format));
194+
}
195+
});
196+
update_tooltips_all();
197+
update_clock();
198+
// update_calendar(agenda_filter.get_filter())
199+
}
200+
201+
// Highlight ongoing based on the current time
202+
function highlight_ongoing() {
203+
$("div#now").remove("#now");
204+
$('.ongoing').removeClass("ongoing");
205+
var agenda_rows=$('[data-slot-start-ts]')
206+
agenda_rows = agenda_rows.filter(function() {
207+
return moment().isBetween(this.slot_start_ts, this.slot_end_ts);
208+
});
209+
agenda_rows.addClass("ongoing");
210+
agenda_rows.first().children("th, td").
211+
prepend($('<div id="now" class="anchor-target"></div>'));
212+
}
213+
214+
// Update tooltips
215+
function update_tooltips() {
216+
var tooltips=$('.timetooltiptext');
217+
tooltips.filter(function() {
218+
return moment().isBetween(this.ustart_ts, this.uend_ts);
219+
}).each(function () {
220+
$(this).html(format_tooltip_table(this.start_ts, this.end_ts));
221+
});
222+
}
223+
224+
// Update all tooltips
225+
function update_tooltips_all() {
226+
var tooltips=$('.timetooltiptext');
227+
tooltips.each(function () {
228+
$(this).html(format_tooltip_table(this.start_ts, this.end_ts));
229+
});
230+
}
231+
232+
// Update clock
233+
function update_clock() {
234+
$('#current-time').html(format_time(moment(), current_timezone, 0));
235+
}
236+
237+
$.urlParam = function(name) {
238+
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
239+
if (results == null) {
240+
return null;
241+
} else {
242+
return results[1] || 0;
243+
}
244+
}
245+
246+
function init_timers() {
247+
var fast_timer = 60000 / (speedup > 600 ? 600 : speedup);
248+
update_clock();
249+
highlight_ongoing();
250+
setInterval(function() { update_clock(); }, fast_timer);
251+
setInterval(function() { highlight_ongoing(); }, fast_timer);
252+
setInterval(function() { update_tooltips(); }, fast_timer);
253+
setInterval(function() { update_tooltips_all(); }, 3600000 / speedup);
254+
}
255+

0 commit comments

Comments
 (0)