diff options
| author | Daniel Friesel <derf@finalrewind.org> | 2018-11-02 21:35:53 +0100 | 
|---|---|---|
| committer | Daniel Friesel <derf@finalrewind.org> | 2018-11-02 21:35:53 +0100 | 
| commit | f87306dc34e91ade3e55d67ac776fd5c7fd3bb15 (patch) | |
| tree | 47be4ecfc7539b1abecb7198f4d8c8d0b9611755 | |
| parent | 6933b8ee45bee33562ac3bf9cd864e6d09e6917b (diff) | |
allow undo for checkins
| -rwxr-xr-x | index.pl | 88 | ||||
| -rw-r--r-- | public/static/js/travelynx-actions.js | 7 | ||||
| -rw-r--r-- | public/static/js/travelynx-actions.min.js | 2 | ||||
| -rw-r--r-- | templates/landingpage.html.ep | 6 | 
4 files changed, 87 insertions, 16 deletions
| @@ -30,7 +30,7 @@ my $dbname = $ENV{TRAVELYNX_DB_FILE} // 'travelynx.sqlite';  my %action_type = (  	checkin  => 1,  	checkout => 2, -	undo     => -1 +	undo     => 3,  );  app->defaults( layout => 'default' ); @@ -174,7 +174,7 @@ app->attr(  		return $self->app->dbh->prepare(  			qq{  			insert into user_actions ( -				user_id, action_id, action_time, +				user_id, action_id, action_time  			) values (  				?, $action_type{undo}, ?  			) @@ -292,6 +292,30 @@ helper 'checkin' => sub {  	}  }; +helper 'undo' => sub { +	my ($self) = @_; + +	my $uid = $self->get_user_id; +	$self->app->get_last_actions_query->execute($uid); +	my $rows = $self->app->get_last_actions_query->fetchall_arrayref; + +	if ( @{$rows} and $rows->[0][0] == $action_type{undo}) { +		return 'Nested undo (undoing an undo) is not supported'; +	} + +	my $success = $self->app->undo_query->execute( +		$self->get_user_id, +		DateTime->now( time_zone => 'Europe/Berlin' )->epoch, +	); + +	if (defined $success) { +		return; +	} +	else { +		return 'INSERT failed'; +	} +}; +  helper 'checkout' => sub {  	my ( $self, $station, $force ) = @_; @@ -513,9 +537,15 @@ helper 'get_user_status' => sub {  	if ( @{$rows} ) {  		my $now = DateTime->now( time_zone => 'Europe/Berlin' ); -		my $ts = epoch_to_dt( $rows->[0][1] ); -		my $checkin_station_name = decode( 'UTF-8', $rows->[0][3] ); -		my @route = split( qr{[|]}, decode( 'UTF-8', $rows->[0][10] // q{} ) ); + +		my @cols = @{$rows->[0]}; +		if (@{$rows} > 2 and $rows->[0][0] == $action_type{undo}) { +			@cols = @{$rows->[2]}; +		} + +		my $ts = epoch_to_dt( $cols[1] ); +		my $checkin_station_name = decode( 'UTF-8', $cols[3] ); +		my @route = split( qr{[|]}, decode( 'UTF-8', $cols[10] // q{} ) );  		my @route_after;  		my $is_after = 0;  		for my $station (@route) { @@ -527,15 +557,15 @@ helper 'get_user_status' => sub {  			}  		}  		return { -			checked_in      => ( $rows->[0][0] == $action_type{checkin} ), +			checked_in      => ( $cols[0] == $action_type{checkin} ),  			timestamp       => $ts, -			timestamp_delta => $now->subtract_datetime($ts), -			station_ds100   => $rows->[0][2], -			station_name    => $rows->[0][3], -			train_type      => $rows->[0][4], -			train_line      => $rows->[0][5], -			train_no        => $rows->[0][6], -			train_id        => $rows->[0][7], +			timestamp_delta => $now->epoch - $ts->epoch, +			station_ds100   => $cols[2], +			station_name    => $cols[3], +			train_type      => $cols[4], +			train_line      => $cols[5], +			train_no        => $cols[6], +			train_id        => $cols[7],  			route           => \@route,  			route_after     => \@route_after,  		}; @@ -600,7 +630,10 @@ post '/action' => sub {  	if ( not $params->{action} ) {  		$self->render( -			json   => {}, +			json   => { +				success => 0, +				error => 'Missing action value', +			},  			status => 400,  		);  		return; @@ -648,6 +681,33 @@ post '/action' => sub {  			);  		}  	} +	elsif ( $params->{action} eq 'undo' ) { +		my $error = $self->undo; +		if ($error) { +			$self->render( +				json => { +					success => 0, +					error   => $error, +				}, +			); +		} +		else { +			$self->render( +				json => { +					success => 1, +				}, +			); +		} +	} +	else { +		$self->render( +			json   => { +				success => 0, +				error => 'invalid action value', +			}, +			status => 400, +		); +	}  };  get '/a/history' => sub { diff --git a/public/static/js/travelynx-actions.js b/public/static/js/travelynx-actions.js index 70c5d39..86ad87d 100644 --- a/public/static/js/travelynx-actions.js +++ b/public/static/js/travelynx-actions.js @@ -39,4 +39,11 @@ $(document).ready(function() {  			link.data('force', true);  		});  	}); +	$('.action-undo').click(function() { +		var link = $(this); +		var req = { +			action: 'undo', +		}; +		tvly_run(link, req, window.location.href); +	});  }); diff --git a/public/static/js/travelynx-actions.min.js b/public/static/js/travelynx-actions.min.js index 2ecfe38..0393b42 100644 --- a/public/static/js/travelynx-actions.min.js +++ b/public/static/js/travelynx-actions.min.js @@ -1 +1 @@ -function tvly_run(t,a,n,i){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');t.hide(),t.after(o),$.post("/action",a,function(a){a.success?$(location).attr("href",n):(M.toast({html:c+" "+a.error}),o.remove(),i&&i(),t.append(" "+c),t.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),a={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,a,"/"+a.station,function(){t.append(" – Keine Echtzeitdaten vorhanden"),t.data("force",!0)})})}); +function tvly_run(t,n,i,a){var c='<i class="material-icons">error</i>',o=$('<div class="progress"><div class="indeterminate"></div></div>');t.hide(),t.after(o),$.post("/action",n,function(n){n.success?$(location).attr("href",i):(M.toast({html:c+" "+n.error}),o.remove(),a&&a(),t.append(" "+c),t.show())})}$(document).ready(function(){$(".action-checkin").click(function(){var t=$(this);tvly_run(t,{action:"checkin",station:t.data("station"),train:t.data("train")},"/")}),$(".action-checkout").click(function(){var t=$(this),n={action:"checkout",station:t.data("station"),force:t.data("force")};tvly_run(t,n,"/"+n.station,function(){t.append(" – Keine Echtzeitdaten vorhanden"),t.data("force",!0)})}),$(".action-undo").click(function(){tvly_run($(this),{action:"undo"},window.location.href)})}); diff --git a/templates/landingpage.html.ep b/templates/landingpage.html.ep index 5d03262..00a67cc 100644 --- a/templates/landingpage.html.ep +++ b/templates/landingpage.html.ep @@ -7,7 +7,11 @@  					<span class="card-title">Hallo, <%= $self->get_user_name %>!</span>  					<p>Du bist gerade eingecheckt in  						<%= $status->{train_type} %> <%= $status->{train_no} %> -						ab <%= $status->{station_name} %>.</p> +						ab <%= $status->{station_name} %>. +						% if ($status->{timestamp_delta} < 3600) { +							<a class="action-undo"><i class="material-icons">undo</i> Rückgängig</a> +						% } +						</p>  					<p>Auschecken?</p>  					<table>  						<tbody> | 
