mirror of
https://github.com/derf/travelynx
synced 2024-12-02 17:29:11 +00:00
live update of next station via javascript
This commit is contained in:
parent
f13b4755c7
commit
663b4dc6d8
4 changed files with 102 additions and 8 deletions
|
@ -2405,6 +2405,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 ) = @_;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
2
public/static/js/travelynx-actions.min.js
vendored
2
public/static/js/travelynx-actions.min.js
vendored
|
@ -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")})});
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue