summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2019-10-29 21:18:46 +0100
committerDaniel Friesel <derf@finalrewind.org>2019-10-29 21:18:46 +0100
commit663b4dc6d89d21caa6b670d69780754b40910d90 (patch)
tree17571683194e5c26a036c69e0f2130280ec31457
parentf13b4755c7db9df079c6fdb0d22679358a9585b9 (diff)
live update of next station via javascript
-rwxr-xr-xlib/Travelynx.pm30
-rw-r--r--public/static/js/travelynx-actions.js68
-rw-r--r--public/static/js/travelynx-actions.min.js2
-rw-r--r--templates/_checked_in.html.ep10
4 files changed, 102 insertions, 8 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index b29d63b..84310d9 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -2406,6 +2406,36 @@ sub startup {
);
$self->helper(
+ 'journey_to_ajax_route' => sub {
+ my ( $self, $journey ) = @_;
+
+ my @route;
+
+ for my $station ( @{ $journey->{route_after} } ) {
+ my $station_desc = $station->[0];
+ if ( $station->[1]{rt_arr} ) {
+ $station_desc .= $station->[1]{sched_arr}->strftime(';%s');
+ $station_desc .= $station->[1]{rt_arr}->strftime(';%s');
+ if ( $station->[1]{rt_dep} ) {
+ $station_desc
+ .= $station->[1]{sched_dep}->strftime(';%s');
+ $station_desc .= $station->[1]{rt_dep}->strftime(';%s');
+ }
+ else {
+ $station_desc .= ';0;0';
+ }
+ }
+ else {
+ $station_desc .= ';0;0;0;0';
+ }
+ push( @route, $station_desc );
+ }
+
+ return join( '|', @route );
+ }
+ );
+
+ $self->helper(
'get_user_status' => sub {
my ( $self, $uid ) = @_;
diff --git a/public/static/js/travelynx-actions.js b/public/static/js/travelynx-actions.js
index 0df6989..92a0a58 100644
--- a/public/static/js/travelynx-actions.js
+++ b/public/static/js/travelynx-actions.js
@@ -1,14 +1,40 @@
+var j_departure = 0;
var j_duration = 0;
var j_arrival = 0;
+var j_dest = '';
+var j_stops = [];
function upd_journey_data() {
$('.countdown').each(function() {
- j_duration = $(this).data('duration');
- j_arrival = $(this).data('arrival');
+ var journey_data = $(this).data('journey');
+ if (journey_data) {
+ journey_data = journey_data.split(';');
+ j_departure = parseInt(journey_data[0]);
+ j_arrival = parseInt(journey_data[1]);
+ j_duration = j_arrival - j_departure;
+ }
+ var journey_dest = $(this).data('dest');
+ if (journey_dest) {
+ j_dest = journey_dest;
+ }
+ var stops = $(this).data('route');
+ if (stops) {
+ stops = stops.split('|');
+ j_stops = [];
+ for (var stop_id in stops) {
+ var stopdata = stops[stop_id].split(';');
+ for (var i = 1; i < 5; i++) {
+ stopdata[i] = parseInt(stopdata[i]);
+ }
+ j_stops.push(stopdata);
+ }
+ }
});
}
function upd_countdown() {
var now = Date.now() / 1000;
- if (j_arrival > 0) {
+ if (j_departure > now) {
+ $('.countdown').text('Abfahrt in ' + Math.round((j_departure - now)/60) + ' Minuten');
+ } else if (j_arrival > 0) {
if (j_arrival > now) {
$('.countdown').text('Ankunft in ' + Math.round((j_arrival - now)/60) + ' Minuten');
} else {
@@ -16,6 +42,22 @@ function upd_countdown() {
}
}
}
+function hhmm(epoch) {
+ var date = new Date(epoch * 1000);
+ var h = date.getHours();
+ var m = date.getMinutes();
+ return (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m);
+}
+function odelay(sched, rt) {
+ if (sched < rt) {
+ return ' (+' + ((rt - sched) / 60) + ')';
+ }
+ else if (sched == rt) {
+ return '';
+ }
+ return ' (' + ((rt - sched) / 60) + ')';
+}
+
function tvly_run(link, req, err_callback) {
var error_icon = '<i class="material-icons">error</i>';
var progressbar = $('<div class="progress"><div class="indeterminate"></div></div>');
@@ -74,6 +116,26 @@ function tvly_journey_progress() {
progress = 1;
}
$('.progress .determinate').css('width', (progress * 100) + '%');
+
+ for (stop in j_stops) {
+ var stop_name = j_stops[stop][0];
+ var sched_arr = j_stops[stop][1];
+ var rt_arr = j_stops[stop][2];
+ var sched_dep = j_stops[stop][3];
+ var rt_dep = j_stops[stop][4];
+ if (stop_name == j_dest) {
+ $('.next-stop').html('');
+ break;
+ }
+ if ((rt_arr != 0) && (rt_arr - now > 0)) {
+ $('.next-stop').html(stop_name + '<br/>' + hhmm(rt_arr) + odelay(sched_arr, rt_arr));
+ break;
+ }
+ if ((rt_dep != 0) && (rt_dep - now > 0)) {
+ $('.next-stop').html(stop_name + '<br/>' + hhmm(rt_arr) + ' → ' + hhmm(rt_dep) + odelay(sched_dep, rt_dep));
+ break;
+ }
+ }
setTimeout(tvly_journey_progress, 5000);
}
}
diff --git a/public/static/js/travelynx-actions.min.js b/public/static/js/travelynx-actions.min.js
index 8af5f9f..fdfeab8 100644
--- a/public/static/js/travelynx-actions.min.js
+++ b/public/static/js/travelynx-actions.min.js
@@ -1 +1 @@
-function upd_journey_data(){$(".countdown").each(function(){j_duration=$(this).data("duration"),j_arrival=$(this).data("arrival")})}function upd_countdown(){var t=Date.now()/1e3;j_arrival>0&&(j_arrival>t?$(".countdown").text("Ankunft in "+Math.round((j_arrival-t)/60)+" Minuten"):$(".countdown").text("Ziel erreicht"))}function tvly_run(t,a,e){var n='<i class="material-icons">error</i>',i=$('<div class="progress"><div class="indeterminate"></div></div>');t.hide(),t.after(i),$.post("/action",a,function(a){a.success?$(location).attr("href",a.redirect_to):(M.toast({html:n+" "+a.error}),i.remove(),e&&e(),t.append(" "+n),t.show())})}function tvly_update(){$.get("/ajax/status_card.html",function(t){$(".statuscol").html(t),tvly_reg_handlers(),upd_journey_data(),setTimeout(tvly_update,4e4)}).fail(function(){$(".sync-failed-marker").css("display","block"),upd_countdown(),setTimeout(tvly_update,5e3)})}function tvly_update_public(){var t;$(".publicstatuscol").each(function(){t=$(this).data("user")}),$.get("/ajax/status/"+t+".html",function(t){$(".publicstatuscol").html(t),upd_journey_data(),setTimeout(tvly_update_public,4e4)}).fail(function(){$(".sync-failed-marker").css("display","block"),upd_countdown(),setTimeout(tvly_update_public,5e3)})}function tvly_journey_progress(){var t=Date.now()/1e3,a=0;j_duration>0&&(a=1-(j_arrival-t)/j_duration,a<0&&(a=0),a>1&&(a=1),$(".progress .determinate").css("width",100*a+"%"),setTimeout(tvly_journey_progress,5e3))}function tvly_reg_handlers(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train"),dest:t.data("dest")})}),$(".action-checkout").click(function(){var t=$(this),a={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,a,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){var t=$(this);tvly_run(t,{action:"undo",undo_id:t.data("id")})}),$(".action-cancelled-from").click(function(){var t=$(this);tvly_run(t,{action:"cancelled_from",station:t.data("station"),train:t.data("train")})}),$(".action-cancelled-to").click(function(){var t=$(this);tvly_run(t,{action:"cancelled_to",station:t.data("station"),force:!0})}),$(".action-delete").click(function(){var t=$(this),a={action:"delete",id:t.data("id"),checkin:t.data("checkin"),checkout:t.data("checkout")};really_delete=confirm("Diese Zugfahrt wirklich löschen? Der Eintrag wird sofort aus der Datenbank entfernt und kann nicht wiederhergestellt werden."),really_delete&&tvly_run(t,a)}),$(".action-share").click(function(){navigator.share?(shareObj={text:$(this).data("text")},$(this).data("url")&&(shareObj.url=$(this).data("url")),navigator.share(shareObj)):$(this).data("url")&&(location.href=$(this).data("url"))}),!$(".action-share").length||navigator.share||$(".action-share").data("url")||$(".action-share").css("display","none")}var j_duration=0,j_arrival=0;$(document).ready(function(){tvly_reg_handlers(),$(".statuscol .autorefresh").length&&(upd_journey_data(),setTimeout(tvly_update,4e4),setTimeout(tvly_journey_progress,5e3)),$(".publicstatuscol .autorefresh").length&&(upd_journey_data(),setTimeout(tvly_update_public,4e4),setTimeout(tvly_journey_progress,5e3)),$("a[href]").click(function(){$("nav .preloader-wrapper").addClass("active")})});
+function upd_journey_data(){$(".countdown").each(function(){var t=$(this).data("journey");t&&(t=t.split(";"),j_departure=parseInt(t[0]),j_arrival=parseInt(t[1]),j_duration=j_arrival-j_departure);var a=$(this).data("dest");a&&(j_dest=a);var e=$(this).data("route");if(e){e=e.split("|"),j_stops=[];for(var n in e){for(var r=e[n].split(";"),o=1;o<5;o++)r[o]=parseInt(r[o]);j_stops.push(r)}}})}function upd_countdown(){var t=Date.now()/1e3;j_departure>t?$(".countdown").text("Abfahrt in "+Math.round((j_departure-t)/60)+" Minuten"):j_arrival>0&&(j_arrival>t?$(".countdown").text("Ankunft in "+Math.round((j_arrival-t)/60)+" Minuten"):$(".countdown").text("Ziel erreicht"))}function hhmm(t){var a=new Date(1e3*t),e=a.getHours(),n=a.getMinutes();return(e<10?"0"+e:e)+":"+(n<10?"0"+n:n)}function odelay(t,a){return t<a?" (+"+(a-t)/60+")":t==a?"":" ("+(a-t)/60+")"}function tvly_run(t,a,e){var n='<i class="material-icons">error</i>',r=$('<div class="progress"><div class="indeterminate"></div></div>');t.hide(),t.after(r),$.post("/action",a,function(a){a.success?$(location).attr("href",a.redirect_to):(M.toast({html:n+" "+a.error}),r.remove(),e&&e(),t.append(" "+n),t.show())})}function tvly_update(){$.get("/ajax/status_card.html",function(t){$(".statuscol").html(t),tvly_reg_handlers(),upd_journey_data(),setTimeout(tvly_update,4e4)}).fail(function(){$(".sync-failed-marker").css("display","block"),upd_countdown(),setTimeout(tvly_update,5e3)})}function tvly_update_public(){var t;$(".publicstatuscol").each(function(){t=$(this).data("user")}),$.get("/ajax/status/"+t+".html",function(t){$(".publicstatuscol").html(t),upd_journey_data(),setTimeout(tvly_update_public,4e4)}).fail(function(){$(".sync-failed-marker").css("display","block"),upd_countdown(),setTimeout(tvly_update_public,5e3)})}function tvly_journey_progress(){var t=Date.now()/1e3,a=0;if(j_duration>0){a=1-(j_arrival-t)/j_duration,a<0&&(a=0),a>1&&(a=1),$(".progress .determinate").css("width",100*a+"%");for(stop in j_stops){var e=j_stops[stop][0],n=j_stops[stop][1],r=j_stops[stop][2],o=j_stops[stop][3],i=j_stops[stop][4];if(e==j_dest){$(".next-stop").html("");break}if(0!=r&&r-t>0){$(".next-stop").html(e+"<br/>"+hhmm(r)+odelay(n,r));break}if(0!=i&&i-t>0){$(".next-stop").html(e+"<br/>"+hhmm(r)+" → "+hhmm(i)+odelay(o,i));break}}setTimeout(tvly_journey_progress,5e3)}}function tvly_reg_handlers(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train"),dest:t.data("dest")})}),$(".action-checkout").click(function(){var t=$(this),a={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,a,function(){t.append(" – Ohne Echtzeitdaten auschecken?"),t.data("force",!0)})}),$(".action-undo").click(function(){var t=$(this);tvly_run(t,{action:"undo",undo_id:t.data("id")})}),$(".action-cancelled-from").click(function(){var t=$(this);tvly_run(t,{action:"cancelled_from",station:t.data("station"),train:t.data("train")})}),$(".action-cancelled-to").click(function(){var t=$(this);tvly_run(t,{action:"cancelled_to",station:t.data("station"),force:!0})}),$(".action-delete").click(function(){var t=$(this),a={action:"delete",id:t.data("id"),checkin:t.data("checkin"),checkout:t.data("checkout")};really_delete=confirm("Diese Zugfahrt wirklich löschen? Der Eintrag wird sofort aus der Datenbank entfernt und kann nicht wiederhergestellt werden."),really_delete&&tvly_run(t,a)}),$(".action-share").click(function(){navigator.share?(shareObj={text:$(this).data("text")},$(this).data("url")&&(shareObj.url=$(this).data("url")),navigator.share(shareObj)):$(this).data("url")&&(location.href=$(this).data("url"))}),!$(".action-share").length||navigator.share||$(".action-share").data("url")||$(".action-share").css("display","none")}var j_departure=0,j_duration=0,j_arrival=0,j_dest="",j_stops=[];$(document).ready(function(){tvly_reg_handlers(),$(".statuscol .autorefresh").length&&(upd_journey_data(),setTimeout(tvly_update,4e4),setTimeout(tvly_journey_progress,5e3)),$(".publicstatuscol .autorefresh").length&&(upd_journey_data(),setTimeout(tvly_update_public,4e4),setTimeout(tvly_journey_progress,5e3)),$("a[href]").click(function(){$("nav .preloader-wrapper").addClass("active")})});
diff --git a/templates/_checked_in.html.ep b/templates/_checked_in.html.ep
index 87b94f6..8d59c82 100644
--- a/templates/_checked_in.html.ep
+++ b/templates/_checked_in.html.ep
@@ -5,8 +5,10 @@
<span class="card-title">Eingecheckt in <%= $journey->{train_type} %> <%= $journey->{train_no} %></span>
<p>
<div class="center-align countdown"
- data-duration="<%= $journey->{journey_duration} // 0 %>"
- data-arrival="<%= $journey->{real_arrival}->epoch %>">
+ data-journey="<%= $journey->{real_departure}->epoch %>;<%= <%= $journey->{real_arrival}->epoch %>"
+ data-route="<%= journey_to_ajax_route($journey) %>"
+ data-dest="<%= $journey->{arr_name} %>"
+ >
% if ($journey->{boarding_countdown} > 120) {
Einfahrt in <%= sprintf('%.f', $journey->{boarding_countdown} / 60) %> Minuten<br/>
% }
@@ -108,7 +110,7 @@
noch nicht bekannt
% }
</div>
- <div class="center-align hide-on-small-only">
+ <div class="center-align hide-on-small-only next-stop">
% for my $station (@{$journey->{route_after}}) {
% if ($station->[0] eq $journey->{arr_name}) {
% last;
@@ -133,7 +135,7 @@
</div>
<div style="clear: both;">
</div>
- <div class="hide-on-med-and-up" style="margin-top: 2ex;">
+ <div class="hide-on-med-and-up next-stop" style="margin-top: 2ex;">
% for my $station (@{$journey->{route_after}}) {
% if ($station->[0] eq $journey->{arr_name}) {
% last;