allow checkin from connections view
This commit is contained in:
parent
7960114f71
commit
d9d3aac792
12 changed files with 121 additions and 60 deletions
|
@ -175,6 +175,12 @@ sub startup {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$self->helper(
|
||||||
|
'now' => sub {
|
||||||
|
return DateTime->now( time_zone => 'Europe/Berlin' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$self->helper(
|
$self->helper(
|
||||||
'numify_skipped_stations' => sub {
|
'numify_skipped_stations' => sub {
|
||||||
my ( $self, $count ) = @_;
|
my ( $self, $count ) = @_;
|
||||||
|
@ -1489,7 +1495,7 @@ sub startup {
|
||||||
my $uid = $opt{uid} // $self->current_user->{id};
|
my $uid = $opt{uid} // $self->current_user->{id};
|
||||||
my $threshold = $opt{threshold}
|
my $threshold = $opt{threshold}
|
||||||
// DateTime->now( time_zone => 'Europe/Berlin' )
|
// DateTime->now( time_zone => 'Europe/Berlin' )
|
||||||
->subtract( weeks => 60 );
|
->subtract( weeks => 6 );
|
||||||
my $db = $opt{db} // $self->pg->db;
|
my $db = $opt{db} // $self->pg->db;
|
||||||
|
|
||||||
my $journey = $db->select( 'in_transit', ['checkout_station_id'],
|
my $journey = $db->select( 'in_transit', ['checkout_station_id'],
|
||||||
|
@ -1504,7 +1510,7 @@ sub startup {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
limit => 1,
|
limit => 1,
|
||||||
order_by => { -desc => 'real_dep_ts' }
|
order_by => { -desc => 'real_departure' }
|
||||||
}
|
}
|
||||||
)->hash;
|
)->hash;
|
||||||
}
|
}
|
||||||
|
@ -1547,11 +1553,14 @@ sub startup {
|
||||||
}
|
}
|
||||||
|
|
||||||
my @destinations = $self->get_connection_targets(%opt);
|
my @destinations = $self->get_connection_targets(%opt);
|
||||||
my $stationboard
|
|
||||||
= $self->get_departures( $status->{arr_ds100}, 0, 60 );
|
|
||||||
|
|
||||||
@destinations = grep { $_ ne $status->{dep_name} } @destinations;
|
@destinations = grep { $_ ne $status->{dep_name} } @destinations;
|
||||||
|
|
||||||
|
if ( not @destinations ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $stationboard
|
||||||
|
= $self->get_departures( $status->{arr_ds100}, 0, 60 );
|
||||||
if ( $stationboard->{errstr} ) {
|
if ( $stationboard->{errstr} ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,7 @@ sub log_action {
|
||||||
|
|
||||||
my ( $train, $error )
|
my ( $train, $error )
|
||||||
= $self->checkin( $params->{station}, $params->{train} );
|
= $self->checkin( $params->{station}, $params->{train} );
|
||||||
|
my $destination = $params->{dest};
|
||||||
|
|
||||||
if ($error) {
|
if ($error) {
|
||||||
$self->render(
|
$self->render(
|
||||||
|
@ -154,7 +155,7 @@ sub log_action {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
elsif ( not $destination ) {
|
||||||
$self->render(
|
$self->render(
|
||||||
json => {
|
json => {
|
||||||
success => 1,
|
success => 1,
|
||||||
|
@ -162,6 +163,19 @@ sub log_action {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
# Silently ignore errors -- if they are permanent, the user will see
|
||||||
|
# them when selecting the destination manually.
|
||||||
|
my ( $still_checked_in, undef )
|
||||||
|
= $self->checkout( $destination, 0 );
|
||||||
|
my $station_link = '/s/' . $destination;
|
||||||
|
$self->render(
|
||||||
|
json => {
|
||||||
|
success => 1,
|
||||||
|
redirect_to => $still_checked_in ? '/' : $station_link,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elsif ( $params->{action} eq 'checkout' ) {
|
elsif ( $params->{action} eq 'checkout' ) {
|
||||||
my ( $still_checked_in, $error )
|
my ( $still_checked_in, $error )
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
const CACHE_NAME = 'static-cache-v23';
|
const CACHE_NAME = 'static-cache-v24';
|
||||||
const FILES_TO_CACHE = [
|
const FILES_TO_CACHE = [
|
||||||
'/favicon.ico',
|
'/favicon.ico',
|
||||||
'/offline.html',
|
'/offline.html',
|
||||||
'/static/v23/css/light.min.css',
|
'/static/v24/css/light.min.css',
|
||||||
'/static/v23/css/dark.min.css',
|
'/static/v24/css/dark.min.css',
|
||||||
'/static/v23/css/material-icons.css',
|
'/static/v24/css/material-icons.css',
|
||||||
'/static/v23/css/local.css',
|
'/static/v24/css/local.css',
|
||||||
'/static/v23/fonts/MaterialIcons-Regular.woff2',
|
'/static/v24/fonts/MaterialIcons-Regular.woff2',
|
||||||
'/static/v23/fonts/MaterialIcons-Regular.woff',
|
'/static/v24/fonts/MaterialIcons-Regular.woff',
|
||||||
'/static/v23/fonts/MaterialIcons-Regular.ttf',
|
'/static/v24/fonts/MaterialIcons-Regular.ttf',
|
||||||
'/static/v23/js/jquery-3.4.1.min.js',
|
'/static/v24/js/jquery-3.4.1.min.js',
|
||||||
'/static/v23/js/materialize.min.js',
|
'/static/v24/js/materialize.min.js',
|
||||||
'/static/v23/js/travelynx-actions.min.js',
|
'/static/v24/js/travelynx-actions.min.js',
|
||||||
'/static/v23/js/autocomplete.min.js',
|
'/static/v24/js/autocomplete.min.js',
|
||||||
'/static/v23/js/geolocation.min.js',
|
'/static/v24/js/geolocation.min.js',
|
||||||
];
|
];
|
||||||
|
|
||||||
self.addEventListener('install', (evt) => {
|
self.addEventListener('install', (evt) => {
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
font-family: 'Material Icons';
|
font-family: 'Material Icons';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: url(/static/v23/fonts/MaterialIcons-Regular.eot); /* For IE6-8 */
|
src: url(/static/v24/fonts/MaterialIcons-Regular.eot); /* For IE6-8 */
|
||||||
src: local('Material Icons'),
|
src: local('Material Icons'),
|
||||||
local('MaterialIcons-Regular'),
|
local('MaterialIcons-Regular'),
|
||||||
url(/static/v23/fonts/MaterialIcons-Regular.woff2) format('woff2'),
|
url(/static/v24/fonts/MaterialIcons-Regular.woff2) format('woff2'),
|
||||||
url(/static/v23/fonts/MaterialIcons-Regular.woff) format('woff'),
|
url(/static/v24/fonts/MaterialIcons-Regular.woff) format('woff'),
|
||||||
url(/static/v23/fonts/MaterialIcons-Regular.ttf) format('truetype');
|
url(/static/v24/fonts/MaterialIcons-Regular.ttf) format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.material-icons {
|
.material-icons {
|
||||||
|
|
|
@ -84,6 +84,7 @@ function tvly_reg_handlers() {
|
||||||
action: 'checkin',
|
action: 'checkin',
|
||||||
station: link.data('station'),
|
station: link.data('station'),
|
||||||
train: link.data('train'),
|
train: link.data('train'),
|
||||||
|
dest: link.data('dest'),
|
||||||
};
|
};
|
||||||
tvly_run(link, req);
|
tvly_run(link, req);
|
||||||
});
|
});
|
||||||
|
|
2
public/static/js/travelynx-actions.min.js
vendored
2
public/static/js/travelynx-actions.min.js
vendored
|
@ -1 +1 @@
|
||||||
var j_duration=0,j_arrival=0;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;0<j_arrival&&(t<j_arrival?$(".countdown").text("Ankunft in "+Math.round((j_arrival-t)/60)+" Minuten"):$(".countdown").text("Ziel erreicht"))}function tvly_run(a,t,e){var n='<i class="material-icons">error</i>',i=$('<div class="progress"><div class="indeterminate"></div></div>');a.hide(),a.after(i),$.post("/action",t,function(t){t.success?$(location).attr("href",t.redirect_to):(M.toast({html:n+" "+t.error}),i.remove(),e&&e(),a.append(" "+n),a.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;0<j_duration&&((a=1-(j_arrival-t)/j_duration)<0&&(a=0),1<a&&(a=1),$(".progress .determinate").css("width",100*a+"%"),setTimeout(tvly_journey_progress,5e3))}function tvly_reg_handlers(){$(".action-checkin").click(function(){var t=$(this),a={action:"checkin",station:t.data("station"),train:t.data("train")};tvly_run(t,a)}),$(".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),a={action:"undo",undo_id:t.data("id")};tvly_run(t,a)}),$(".action-cancelled-from").click(function(){var t=$(this),a={action:"cancelled_from",station:t.data("station"),train:t.data("train")};tvly_run(t,a)}),$(".action-cancelled-to").click(function(){var t=$(this),a={action:"cancelled_to",station:t.data("station"),force:!0};tvly_run(t,a)}),$(".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))}),$(".action-share").length&&!navigator.share&&$(".action-share").css("display","none")}$(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(){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))}),$(".action-share").length&&!navigator.share&&$(".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")})});
|
||||||
|
|
|
@ -3,27 +3,27 @@
|
||||||
"short_name": "Travelynx",
|
"short_name": "Travelynx",
|
||||||
"scope": "/",
|
"scope": "/",
|
||||||
"icons": [{
|
"icons": [{
|
||||||
"src": "/static/v23/icons/icon-128x128.png",
|
"src": "/static/v24/icons/icon-128x128.png",
|
||||||
"sizes": "128x128",
|
"sizes": "128x128",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}, {
|
}, {
|
||||||
"src": "/static/v23/icons/icon-144x144.png",
|
"src": "/static/v24/icons/icon-144x144.png",
|
||||||
"sizes": "144x144",
|
"sizes": "144x144",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}, {
|
}, {
|
||||||
"src": "/static/v23/icons/icon-152x152.png",
|
"src": "/static/v24/icons/icon-152x152.png",
|
||||||
"sizes": "152x152",
|
"sizes": "152x152",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}, {
|
}, {
|
||||||
"src": "/static/v23/icons/icon-192x192.png",
|
"src": "/static/v24/icons/icon-192x192.png",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}, {
|
}, {
|
||||||
"src": "/static/v23/icons/icon-256x256.png",
|
"src": "/static/v24/icons/icon-256x256.png",
|
||||||
"sizes": "256x256",
|
"sizes": "256x256",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}, {
|
}, {
|
||||||
"src": "/static/v23/icons/icon-512x512.png",
|
"src": "/static/v24/icons/icon-512x512.png",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
}],
|
}],
|
||||||
|
|
|
@ -79,35 +79,7 @@
|
||||||
% }
|
% }
|
||||||
% if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} < (20*60)) {
|
% if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} < (20*60)) {
|
||||||
% if (my @connections = get_connecting_trains()) {
|
% if (my @connections = get_connecting_trains()) {
|
||||||
<span class="card-title" style="margin-top: 2ex;">Verbindungen</span>
|
%= include '_connections', connections => \@connections, checkin_from => $journey->{arrival_countdown} < 0 ? $journey->{arr_ds100} : undef;
|
||||||
<div class="hide-on-med-and-up"><table><tbody>
|
|
||||||
% for my $res (@connections) {
|
|
||||||
% my ($train, $via) = @{$res};
|
|
||||||
<tr>
|
|
||||||
<td><%= $train->line %></td>
|
|
||||||
<td><%= $via %></td>
|
|
||||||
<td><%= $train->departure->strftime('%H:%M') %>
|
|
||||||
% if ($train->departure_delay) {
|
|
||||||
%= sprintf('(%+d)', $train->departure_delay)
|
|
||||||
% }
|
|
||||||
<br/>Gleis <%= $train->platform %></td>
|
|
||||||
</tr>
|
|
||||||
% }
|
|
||||||
</tbody></table></div>
|
|
||||||
<div class="hide-on-small-only"><table><tbody>
|
|
||||||
% for my $res (@connections) {
|
|
||||||
% my ($train, $via) = @{$res};
|
|
||||||
<tr>
|
|
||||||
<td><%= $train->line %></td>
|
|
||||||
<td><%= $via %></td>
|
|
||||||
<td><%= $train->departure->strftime('%H:%M') %>
|
|
||||||
% if ($train->departure_delay) {
|
|
||||||
%= sprintf('(%+d)', $train->departure_delay)
|
|
||||||
% }
|
|
||||||
</td><td>Gleis <%= $train->platform %></td>
|
|
||||||
</tr>
|
|
||||||
% }
|
|
||||||
</tbody></table></div>
|
|
||||||
% }
|
% }
|
||||||
% }
|
% }
|
||||||
% if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} <= 0) {
|
% if (defined $journey->{arrival_countdown} and $journey->{arrival_countdown} <= 0) {
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
<span class="card-title">Ausgecheckt</span>
|
<span class="card-title">Ausgecheckt</span>
|
||||||
<p>Aus <%= $journey->{train_type} %> <%= $journey->{train_no} %>
|
<p>Aus <%= $journey->{train_type} %> <%= $journey->{train_no} %>
|
||||||
bis <a href="/s/<%= $journey->{arr_ds100} %>"><%= $journey->{arr_name} %></a></p>
|
bis <a href="/s/<%= $journey->{arr_ds100} %>"><%= $journey->{arr_name} %></a></p>
|
||||||
|
% if (now()->epoch - $journey->{timestamp}->epoch < (30*60)) {
|
||||||
|
% if (my @connections = get_connecting_trains()) {
|
||||||
|
%= include '_connections', connections => \@connections, checkin_from => $journey->{arr_ds100};
|
||||||
|
% }
|
||||||
|
% }
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action">
|
<div class="card-action">
|
||||||
<a class="action-undo" data-id="<%= $journey->{journey_id} %>">
|
<a class="action-undo" data-id="<%= $journey->{journey_id} %>">
|
||||||
|
|
60
templates/_connections.html.ep
Normal file
60
templates/_connections.html.ep
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<span class="card-title" style="margin-top: 2ex;">Verbindungen</span>
|
||||||
|
% if ($checkin_from) {
|
||||||
|
<p>Zug auswählen zum Einchecken mit Zielwahl.</p>
|
||||||
|
% }
|
||||||
|
<div class="hide-on-med-and-up"><table><tbody>
|
||||||
|
% for my $res (@{$connections}) {
|
||||||
|
% my ($train, $via) = @{$res};
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
% if ($checkin_from) {
|
||||||
|
<a class="action-checkin" data-station="<%= $checkin_from %>" data-train="<%= $train->train_id %>" data-dest="<%= $via %>"><%= $train->line %></a>
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
%= $train->line
|
||||||
|
% }
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
% if ($checkin_from) {
|
||||||
|
<a class="action-checkin" data-station="<%= $checkin_from %>" data-train="<%= $train->train_id %>" data-dest="<%= $via %>"><%= $via %></a>
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
%= $via
|
||||||
|
% }
|
||||||
|
</td>
|
||||||
|
<td><%= $train->departure->strftime('%H:%M') %>
|
||||||
|
% if ($train->departure_delay) {
|
||||||
|
%= sprintf('(%+d)', $train->departure_delay)
|
||||||
|
% }
|
||||||
|
<br/>Gleis <%= $train->platform %></td>
|
||||||
|
</tr>
|
||||||
|
% }
|
||||||
|
</tbody></table></div>
|
||||||
|
<div class="hide-on-small-only"><table><tbody>
|
||||||
|
% for my $res (@{$connections}) {
|
||||||
|
% my ($train, $via) = @{$res};
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
% if ($checkin_from) {
|
||||||
|
<a class="action-checkin" data-station="<%= $checkin_from %>" data-train="<%= $train->train_id %>" data-dest="<%= $via %>"><%= $train->line %></a>
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
%= $train->line
|
||||||
|
% }
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
% if ($checkin_from) {
|
||||||
|
<a class="action-checkin" data-station="<%= $checkin_from %>" data-train="<%= $train->train_id %>" data-dest="<%= $via %>"><%= $via %></a>
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
%= $via
|
||||||
|
% }
|
||||||
|
</td>
|
||||||
|
<td><%= $train->departure->strftime('%H:%M') %>
|
||||||
|
% if ($train->departure_delay) {
|
||||||
|
%= sprintf('(%+d)', $train->departure_delay)
|
||||||
|
% }
|
||||||
|
</td><td>Gleis <%= $train->platform %></td>
|
||||||
|
</tr>
|
||||||
|
% }
|
||||||
|
</tbody></table></div>
|
|
@ -9,7 +9,7 @@
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
<meta name="apple-mobile-web-app-title" content="Travelynx">
|
<meta name="apple-mobile-web-app-title" content="Travelynx">
|
||||||
% my $av = 'v23'; # asset version
|
% my $av = 'v24'; # asset version
|
||||||
<link rel="icon" type="image/png" href="/static/<%= $av %>/icons/icon-16x16.png" sizes="16x16">
|
<link rel="icon" type="image/png" href="/static/<%= $av %>/icons/icon-16x16.png" sizes="16x16">
|
||||||
<link rel="icon" type="image/png" href="/static/<%= $av %>/icons/icon-32x32.png" sizes="32x32">
|
<link rel="icon" type="image/png" href="/static/<%= $av %>/icons/icon-32x32.png" sizes="32x32">
|
||||||
<link rel="icon" type="image/png" href="/static/<%= $av %>/icons/icon-96x96.png" sizes="96x96">
|
<link rel="icon" type="image/png" href="/static/<%= $av %>/icons/icon-96x96.png" sizes="96x96">
|
||||||
|
|
Loading…
Reference in a new issue