summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2023-01-18 18:13:35 +0100
committerDaniel Friesel <derf@finalrewind.org>2023-01-18 18:13:35 +0100
commite9373246175a0853fb56aff4a740f4db7dda7215 (patch)
tree0cde9fbc35979d15bb9636d50004f28782c29b24
parenteb1ed1bb48d54077930d015144636f90b2fc9c15 (diff)
landing page: show past stops if geolocation is unavailable
-rwxr-xr-xlib/Travelynx/Controller/Traveling.pm6
-rwxr-xr-xlib/Travelynx/Model/Journeys.pm38
-rw-r--r--public/static/js/geolocation.js36
-rw-r--r--templates/landingpage.html.ep2
4 files changed, 70 insertions, 12 deletions
diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm
index 9d32c86..357e3bd 100755
--- a/lib/Travelynx/Controller/Traveling.pm
+++ b/lib/Travelynx/Controller/Traveling.pm
@@ -376,6 +376,7 @@ sub homepage {
my ($self) = @_;
if ( $self->is_user_authenticated ) {
my $status = $self->get_user_status;
+ my @recent_targets;
if ( $status->{checked_in} ) {
if ( defined $status->{arrival_countdown}
and $status->{arrival_countdown} < ( 40 * 60 ) )
@@ -414,10 +415,15 @@ sub homepage {
return;
}
}
+ else {
+ @recent_targets = $self->journeys->get_latest_checkout_stations(
+ uid => $self->current_user->{id} );
+ }
$self->render(
'landingpage',
version => $self->app->config->{version} // 'UNKNOWN',
user_status => $status,
+ recent_targets => \@recent_targets,
with_autocomplete => 1,
with_geolocation => 1
);
diff --git a/lib/Travelynx/Model/Journeys.pm b/lib/Travelynx/Model/Journeys.pm
index 05728c0..dfe44b6 100755
--- a/lib/Travelynx/Model/Journeys.pm
+++ b/lib/Travelynx/Model/Journeys.pm
@@ -739,6 +739,44 @@ sub get_latest_checkout_station_id {
return $res_h->{checkout_station_id};
}
+sub get_latest_checkout_stations {
+ my ( $self, %opt ) = @_;
+ my $uid = $opt{uid};
+ my $db = $opt{db} // $self->{pg}->db;
+ my $limit = $opt{limit} // 5;
+
+ my $res = $db->select(
+ 'journeys_str',
+ [ 'arr_name', 'arr_eva' ],
+ {
+ user_id => $uid,
+ cancelled => 0
+ },
+ {
+ limit => $limit,
+ order_by => { -desc => 'real_arr_ts' }
+ }
+ );
+
+ if ( not $res ) {
+ return;
+ }
+
+ my @ret;
+
+ while ( my $row = $res->hash ) {
+ push(
+ @ret,
+ {
+ name => $row->{arr_name},
+ eva => $row->{arr_eva}
+ }
+ );
+ }
+
+ return @ret;
+}
+
sub get_nav_years {
my ( $self, %opt ) = @_;
diff --git a/public/static/js/geolocation.js b/public/static/js/geolocation.js
index f186d2e..5ef0a5c 100644
--- a/public/static/js/geolocation.js
+++ b/public/static/js/geolocation.js
@@ -4,23 +4,36 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
$(document).ready(function() {
- function getPlaceholder() {
+ const getPlaceholder = function() {
return $('div.geolocation div.progress');
}
- var showError = function(header, message, code) {
- getPlaceholder().remove();
- var errnode = $(document.createElement('div'));
+ const showError = function(header, message, code) {
+ const errnode = $(document.createElement('div'));
errnode.attr('class', 'error');
errnode.text(message);
- var headnode = $(document.createElement('strong'));
- headnode.text(header);
+ const headnode = $(document.createElement('strong'));
+ headnode.text(header + ' ');
errnode.prepend(headnode);
$('div.geolocation').append(errnode);
+
+ const recent = $('div.geolocation').data('recent');
+ if (recent) {
+ const stops = recent.split('|');
+ const res = $(document.createElement('p'));
+ $.each(stops, function(i, stop) {
+ const parts = stop.split(';');
+ res.append($('<a class="tablerow" href="/s/' + parts[0] + '"><span>' + parts[1] + '</span></a>'));
+ });
+ $('p.geolocationhint').text('Letzte Ziele:');
+ getPlaceholder().replaceWith(res);
+ } else {
+ getPlaceholder().remove();
+ }
};
- var processResult = function(data) {
+ const processResult = function(data) {
if (data.error) {
showError('Backend-Fehler:', data.error, null);
} else if (data.candidates.length == 0) {
@@ -39,11 +52,11 @@ $(document).ready(function() {
}
};
- var processLocation = function(loc) {
+ const processLocation = function(loc) {
$.post('/geolocation', {lon: loc.coords.longitude, lat: loc.coords.latitude}, processResult);
};
- var processError = function(error) {
+ const processError = function(error) {
if (error.code == error.PERMISSION_DENIED) {
showError('Standortanfrage nicht möglich.', 'Vermutlich fehlen die Rechte im Browser oder der Android Location Service ist deaktiviert.', 'geolocation.error.PERMISSION_DENIED');
} else if (error.code == error.POSITION_UNAVAILABLE) {
@@ -55,8 +68,9 @@ $(document).ready(function() {
}
};
- var geoLocationButton = $('div.geolocation > button');
- var getGeoLocation = function() {
+ const geoLocationButton = $('div.geolocation > button');
+ const recentStops = geoLocationButton.data('recent');
+ const getGeoLocation = function() {
geoLocationButton.replaceWith($('<p class="geolocationhint">Stationen in der Umgebung:</p><div class="progress"><div class="indeterminate"></div></div>'));
navigator.geolocation.getCurrentPosition(processLocation, processError);
}
diff --git a/templates/landingpage.html.ep b/templates/landingpage.html.ep
index 03d0eca..a4bf10c 100644
--- a/templates/landingpage.html.ep
+++ b/templates/landingpage.html.ep
@@ -49,7 +49,7 @@
<div class="card-content">
<span class="card-title">Hallo, <%= current_user->{name} %>!</span>
<p>Du bist gerade nicht eingecheckt.</p>
- <div class="geolocation">
+ <div class="geolocation" data-recent="<%= join('|', map { $_->{eva} . ';' . $_->{name} } @{stash('recent_targets') // []} ) %>">
<button class="btn waves-effect waves-light btn-flat">Stationen in der Umgebung abfragen</button>
</div>
%= form_for 'list_departures' => begin