mirror of
https://github.com/derf/travelynx
synced 2024-11-10 15:04:17 +00:00
Prepare settings and templates for opt-in public travel status
This commit is contained in:
parent
ddea9abc6e
commit
f0d61a4083
7 changed files with 243 additions and 0 deletions
|
@ -774,6 +774,38 @@ sub startup {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$self->helper(
|
||||||
|
'get_privacy_by_name' => sub {
|
||||||
|
my ( $self, $name ) = @_;
|
||||||
|
|
||||||
|
my $res = $self->pg->db->select(
|
||||||
|
'users',
|
||||||
|
[ 'id', 'public_level' ],
|
||||||
|
{
|
||||||
|
name => $name,
|
||||||
|
status => 1
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( my $user = $res->hash ) {
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$self->helper(
|
||||||
|
'set_privacy' => sub {
|
||||||
|
my ( $self, $uid, $public_level ) = @_;
|
||||||
|
|
||||||
|
$self->pg->db->update(
|
||||||
|
'users',
|
||||||
|
{ public_level => $public_level },
|
||||||
|
{ id => $uid }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$self->helper(
|
$self->helper(
|
||||||
'mark_for_password_reset' => sub {
|
'mark_for_password_reset' => sub {
|
||||||
my ( $self, $db, $uid, $token ) = @_;
|
my ( $self, $db, $uid, $token ) = @_;
|
||||||
|
@ -1696,6 +1728,7 @@ sub startup {
|
||||||
$r->get('/recover/:id/:token')->to('account#recover_password');
|
$r->get('/recover/:id/:token')->to('account#recover_password');
|
||||||
$r->get('/register')->to('account#registration_form');
|
$r->get('/register')->to('account#registration_form');
|
||||||
$r->get('/reg/:id/:token')->to('account#verify');
|
$r->get('/reg/:id/:token')->to('account#verify');
|
||||||
|
$r->get('/status/:name')->to('traveling#user_status');
|
||||||
$r->post('/action')->to('traveling#log_action');
|
$r->post('/action')->to('traveling#log_action');
|
||||||
$r->post('/geolocation')->to('traveling#geolocation');
|
$r->post('/geolocation')->to('traveling#geolocation');
|
||||||
$r->post('/list_departures')->to('traveling#redirect_to_station');
|
$r->post('/list_departures')->to('traveling#redirect_to_station');
|
||||||
|
@ -1715,6 +1748,7 @@ sub startup {
|
||||||
);
|
);
|
||||||
|
|
||||||
$authed_r->get('/account')->to('account#account');
|
$authed_r->get('/account')->to('account#account');
|
||||||
|
$authed_r->get('/account/privacy')->to('account#privacy');
|
||||||
$authed_r->get('/ajax/status_card.html')->to('traveling#status_card');
|
$authed_r->get('/ajax/status_card.html')->to('traveling#status_card');
|
||||||
$authed_r->get('/cancelled')->to('traveling#cancelled');
|
$authed_r->get('/cancelled')->to('traveling#cancelled');
|
||||||
$authed_r->get('/change_password')->to('account#password_form');
|
$authed_r->get('/change_password')->to('account#password_form');
|
||||||
|
@ -1728,6 +1762,7 @@ sub startup {
|
||||||
$authed_r->get('/journey/:id')->to('traveling#journey_details');
|
$authed_r->get('/journey/:id')->to('traveling#journey_details');
|
||||||
$authed_r->get('/s/*station')->to('traveling#station');
|
$authed_r->get('/s/*station')->to('traveling#station');
|
||||||
$authed_r->get('/confirm_mail/:token')->to('account#confirm_mail');
|
$authed_r->get('/confirm_mail/:token')->to('account#confirm_mail');
|
||||||
|
$authed_r->post('/account/privacy')->to('account#privacy');
|
||||||
$authed_r->post('/journey/add')->to('traveling#add_journey_form');
|
$authed_r->post('/journey/add')->to('traveling#add_journey_form');
|
||||||
$authed_r->post('/journey/edit')->to('traveling#edit_journey');
|
$authed_r->post('/journey/edit')->to('traveling#edit_journey');
|
||||||
$authed_r->post('/change_password')->to('account#change_password');
|
$authed_r->post('/change_password')->to('account#change_password');
|
||||||
|
|
|
@ -208,6 +208,28 @@ sub do_logout {
|
||||||
$self->redirect_to('/login');
|
$self->redirect_to('/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub privacy {
|
||||||
|
my ($self) = @_;
|
||||||
|
|
||||||
|
my $user = $self->current_user;
|
||||||
|
my $public_level = $user->{is_public};
|
||||||
|
|
||||||
|
if ( $self->param('action') and $self->param('action') eq 'save' ) {
|
||||||
|
if ( $self->param('public_status') ) {
|
||||||
|
$public_level |= 0x02;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$public_level &= ~0x02;
|
||||||
|
}
|
||||||
|
$self->set_privacy( $user->{id}, $public_level );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->param( public_status => $public_level & 0x02 ? 1 : 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->render( 'privacy', name => $user->{name} );
|
||||||
|
}
|
||||||
|
|
||||||
sub change_mail {
|
sub change_mail {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,44 @@ sub homepage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub user_status {
|
||||||
|
my ($self) = @_;
|
||||||
|
|
||||||
|
my $name = $self->stash('name');
|
||||||
|
my $user = $self->get_privacy_by_name($name);
|
||||||
|
|
||||||
|
if ( $user and ( $user->{public_level} & 0x02 ) ) {
|
||||||
|
my $status = $self->get_user_status( $user->{id} );
|
||||||
|
$self->render(
|
||||||
|
'user_status',
|
||||||
|
name => $name,
|
||||||
|
journey => $status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->render('not_found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub public_status_card {
|
||||||
|
my ($self) = @_;
|
||||||
|
|
||||||
|
my $name = $self->stash('name');
|
||||||
|
my $user = $self->get_privacy_by_name($name);
|
||||||
|
|
||||||
|
if ( $user and ( $user->{public_level} & 0x02 ) ) {
|
||||||
|
my $status = $self->get_user_status( $user->{id} );
|
||||||
|
$self->render(
|
||||||
|
'_public_status_card',
|
||||||
|
name => $name,
|
||||||
|
journey => $status
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->render('not_found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub status_card {
|
sub status_card {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
my $status = $self->get_user_status;
|
my $status = $self->get_user_status;
|
||||||
|
|
87
templates/_public_status_card.html.ep
Normal file
87
templates/_public_status_card.html.ep
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
% if ($journey->{checked_in}) {
|
||||||
|
<div class="card green darken-4">
|
||||||
|
<div class="card-content white-text">
|
||||||
|
<span class="card-title"><%= $name %> ist unterwegs</span>
|
||||||
|
<p>
|
||||||
|
In <b><%= $journey->{train_type} %> <%= $journey->{train_no} %></b>
|
||||||
|
% if ($journey->{arr_name}) {
|
||||||
|
von <b><%= $journey->{dep_name} %></b> nach <b><%= $journey->{arr_name} %></b>.
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
ab <b><%= $journey->{dep_name} %></b>.
|
||||||
|
% }
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b><%= $journey->{real_departure}->strftime('%H:%M') %></b>
|
||||||
|
% if ($journey->{real_departure}->epoch != $journey->{sched_departure}->epoch) {
|
||||||
|
(<%= sprintf('%+d', ($journey->{real_departure}->epoch - $journey->{sched_departure}->epoch)/60) %>)
|
||||||
|
% }
|
||||||
|
→
|
||||||
|
% if ($journey->{real_arrival}->epoch) {
|
||||||
|
<b><%= $journey->{real_arrival}->strftime('%H:%M') %></b>
|
||||||
|
% if ($journey->{real_arrival}->epoch != $journey->{sched_arrival}->epoch) {
|
||||||
|
(<%= sprintf('%+d', ($journey->{real_arrival}->epoch - $journey->{sched_arrival}->epoch)/60) %>)
|
||||||
|
% }
|
||||||
|
% }
|
||||||
|
% elsif ($journey->{arr_name}) {
|
||||||
|
noch nicht bekannt
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
unbekannt
|
||||||
|
% }
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<div class="center">
|
||||||
|
% if ($journey->{departure_countdown} > 120) {
|
||||||
|
Abfahrt in <%= sprintf('%.f', $journey->{departure_countdown} / 60) %> Minuten
|
||||||
|
% }
|
||||||
|
% elsif ($journey->{departure_countdown} > 60) {
|
||||||
|
Abfahrt in einer Minute
|
||||||
|
% }
|
||||||
|
% elsif ($journey->{departure_countdown} > 0) {
|
||||||
|
Abfahrt in weniger als einer Minute
|
||||||
|
% }
|
||||||
|
% elsif (defined $journey->{arrival_countdown}) {
|
||||||
|
% if ($journey->{arrival_countdown} > 60) {
|
||||||
|
Ankunft in <%= sprintf('%.f', $journey->{arrival_countdown} / 60) %>
|
||||||
|
Minute<%= sprintf('%.f', $journey->{arrival_countdown} / 60) == 1 ? '' : 'n' %>
|
||||||
|
% }
|
||||||
|
% elsif ($journey->{arrival_countdown} > 0) {
|
||||||
|
Ankunft in weniger als einer Minute
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
Ziel erreicht
|
||||||
|
% }
|
||||||
|
% }
|
||||||
|
% elsif ($journey->{arr_name}) {
|
||||||
|
Ankunft in mehr als zwei Stunden
|
||||||
|
% }
|
||||||
|
</div>
|
||||||
|
<div class="progress green darken-3" style="height: 1ex;">
|
||||||
|
<div class="determinate white" style="width: <%= sprintf('%.2f', 100 * ($journey->{journey_completion} // 0)); %>%;"></div>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
% if (@{$journey->{messages} // []} > 0 and $journey->{messages}[0]) {
|
||||||
|
<p style="margin-bottom: 2ex;">
|
||||||
|
<ul>
|
||||||
|
% for my $message (reverse @{$journey->{messages} // []}) {
|
||||||
|
% if ($journey->{sched_departure}->epoch - $message->[0]->epoch < 1800) {
|
||||||
|
<li> <i class="material-icons tiny">warning</i> <%= $message->[0]->strftime('%H:%M') %>: <%= $message->[1] %></li>
|
||||||
|
% }
|
||||||
|
% }
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
% }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
<div class="card grey darken-4">
|
||||||
|
<div class="card-content white-text">
|
||||||
|
<span class="card-title"><%= $name %> ist gerade nicht eingecheckt</span>
|
||||||
|
<p>
|
||||||
|
Zuletzt gesehen in <%= $journey->{arr_name} %>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
% }
|
|
@ -36,6 +36,20 @@
|
||||||
<th scope="row">Passwort</th>
|
<th scope="row">Passwort</th>
|
||||||
<td><a href="/change_password"><i class="material-icons">edit</i> ändern</a></td>
|
<td><a href="/change_password"><i class="material-icons">edit</i> ändern</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Privatsphäre</th>
|
||||||
|
<td>
|
||||||
|
% if ($acc->{is_public} == 0) {
|
||||||
|
Keine öffentlichen Daten
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
Öffentliche Daten:
|
||||||
|
% }
|
||||||
|
% if ($acc->{is_public} & 0x02) {
|
||||||
|
Status
|
||||||
|
% }
|
||||||
|
<a href="/account/privacy"><i class="material-icons">edit</i> ändern</a></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Registriert am</th>
|
<th scope="row">Registriert am</th>
|
||||||
<td><%= $acc->{registered_at}->strftime('%d.%m.%Y %H:%M') %></td>
|
<td><%= $acc->{registered_at}->strftime('%d.%m.%Y %H:%M') %></td>
|
||||||
|
|
42
templates/privacy.html.ep
Normal file
42
templates/privacy.html.ep
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<h1>Privatsphäre</h1>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
Hier kannst du auswählen, welche Aspekte deines Accounts bzw. deiner
|
||||||
|
Bahnfahrten öffentlich einsehbar sind. Öffentliche Daten sind
|
||||||
|
grundsätzlich für <i>alle</i> einsehbar, die die (leicht erratbare) URL
|
||||||
|
kennen.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2>Öffentliche Daten:</h2>
|
||||||
|
%= form_for '/account/privacy' => (method => 'POST') => begin
|
||||||
|
%= csrf_field
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label>
|
||||||
|
%= check_box public_status => 1
|
||||||
|
<span class="black-text">Aktueller Status</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
Wenn aktiv, ist dein aktueller Status unter <a href="/status/<%= $name
|
||||||
|
%>">/status/<%= $name %></a> abrufbar. Wenn du eingecheckt bist,
|
||||||
|
werden dort Zug, Start- und Zielstation, Abfahrts- und Ankunftszeit
|
||||||
|
gezeigt; andernfalls lediglich der Zielbahnhof der letzten Reise.
|
||||||
|
Wann die letzte Reise beendet wurde, wird bewusst nicht angegeben.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s3 m3 l3">
|
||||||
|
</div>
|
||||||
|
<div class="col s6 m6 l6 center-align">
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="action" value="save">
|
||||||
|
Speichern
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col s3 m3 l3">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
%= end
|
5
templates/user_status.html.ep
Normal file
5
templates/user_status.html.ep
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
%= include '_public_status_card', name => $name, journey => $journey
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in a new issue