Add swipe gestures into motion detail

Adds swipe gestures into motion detail, to nacigate them easily on mobile devices
Animations are left out for now, since they are complex to develop.

Alters the navigation gesture slightly to only work from the edge of a given screen
This commit is contained in:
Sean Engelhardt 2019-02-26 15:30:16 +01:00
parent 798af8c5ab
commit 0ceddd2662
7 changed files with 84 additions and 27 deletions

View File

@ -17,6 +17,16 @@ export abstract class BaseComponent {
*/
private titleSuffix = ' - OpenSlides';
/**
* Holds the coordinates where a swipe gesture was used
*/
protected swipeCoord?: [number, number];
/**
* Holds the time when the user was swiping
*/
protected swipeTime?: number;
/**
* Settings for the TinyMCE editor selector
*/

View File

@ -64,6 +64,12 @@ export abstract class BaseViewComponent extends BaseComponent implements OnDestr
}
}
/**
* To catch swipe gestures.
* Should be overwritten by children which need swipe gestures
*/
protected swipe(e: TouchEvent, when: string): void {}
/**
* automatically dismisses the error snack bar and clears subscriptions
* if the component is destroyed.

View File

@ -60,7 +60,9 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel, M extends B
* Constructor for list view bases
* @param titleService the title serivce
* @param translate the translate service
* @param matSnackBar
* @param matSnackBar showing errors
* @param filterService filter
* @param sortService sorting
*/
public constructor(
titleService: Title,

View File

@ -19,7 +19,7 @@
</div>
<!-- Back and forth buttons -->
<div *ngIf="!editMotion" class="extra-controls-slot on-transition-fade">
<div *ngIf="!editMotion && !vp.isMobile" class="extra-controls-slot on-transition-fade">
<div *ngIf="previousMotion">
<button mat-button (click)="navigateToMotion(previousMotion)">
<!-- possible icons:
@ -103,7 +103,7 @@
</mat-menu>
</os-head-bar>
<div class="content-container">
<div class="content-container" (touchstart)="swipe($event, 'start')" (touchend)="swipe($event, 'end')">
<!-- Title -->
<div class="title on-transition-fade" *ngIf="motion && !editMotion">
<div class="title-line">

View File

@ -28,6 +28,7 @@ import {
} from '../motion-change-recommendation/motion-change-recommendation.component';
import { MotionPdfExportService } from '../../services/motion-pdf-export.service';
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
import { NotifyService } from 'app/core/core-services/notify.service';
import { OperatorService } from 'app/core/core-services/operator.service';
import { PersonalNoteContent } from 'app/shared/models/users/personal-note';
@ -50,7 +51,6 @@ import { ViewMotionNotificationEditMotion, TypeOfNotificationViewMotion } from '
import { ViewStatuteParagraph } from '../../models/view-statute-paragraph';
import { ViewTag } from 'app/site/tags/models/view-tag';
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change';
import { Workflow } from 'app/shared/models/motions/workflow';
/**
@ -1079,10 +1079,12 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
* @param motion target
*/
public navigateToMotion(motion: ViewMotion): void {
this.router.navigate(['../' + motion.id], { relativeTo: this.route });
// update the current motion
this.motion = motion;
this.setSurroundingMotions();
if (motion) {
this.router.navigate(['../' + motion.id], { relativeTo: this.route });
// update the current motion
this.motion = motion;
this.setSurroundingMotions();
}
}
/**
@ -1458,4 +1460,34 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
return StateCssClassMapping[this.motion.state.css_class] || '';
}
public swipe(e: TouchEvent, when: string): void {
const coord: [number, number] = [e.changedTouches[0].pageX, e.changedTouches[0].pageY];
const time = new Date().getTime();
if (when === 'start') {
this.swipeCoord = coord;
this.swipeTime = time;
} else if (when === 'end') {
const direction = [coord[0] - this.swipeCoord[0], coord[1] - this.swipeCoord[1]];
const duration = time - this.swipeTime;
if (
duration < 1000 &&
Math.abs(direction[0]) > 30 && // swipe length to be detected
Math.abs(direction[0]) > Math.abs(direction[1] * 3) // 30° should be "horizontal enough"
) {
if (
direction[0] > 0 // swipe left to right
) {
this.navigateToMotion(this.previousMotion);
}
if (
direction[0] < 0 // swipe left to right
) {
this.navigateToMotion(this.nextMotion);
}
}
}
}
}

View File

@ -3,7 +3,13 @@
<span>({{ getHistoryTimestamp() }})</span>
<a (click)="timeTravel.resumeTime()" translate>Exit</a>
</div>
<mat-sidenav-container #siteContainer class="main-container" (backdropClick)="toggleSideNav()">
<mat-sidenav-container
#siteContainer
class="main-container"
(backdropClick)="toggleSideNav()"
(touchstart)="swipe($event, 'start')"
(touchend)="swipe($event, 'end')"
>
<mat-sidenav
#sideNav
[mode]="vp.isMobile ? 'over' : 'side'"

View File

@ -38,16 +38,6 @@ export class SiteComponent extends BaseComponent implements OnInit {
*/
public isLoggedIn: boolean;
/**
* Holds the coordinates where a swipe gesture was used
*/
private swipeCoord?: [number, number];
/**
* Holds the time when the user was swiping
*/
private swipeTime?: number;
/**
* Holds the typed search query.
*/
@ -171,18 +161,29 @@ export class SiteComponent extends BaseComponent implements OnInit {
} else if (when === 'end') {
const direction = [coord[0] - this.swipeCoord[0], coord[1] - this.swipeCoord[1]];
const duration = time - this.swipeTime;
// definition of a "swipe right" gesture to move in the navigation.
// Required mobile view
// works anywhere on the screen, but could be limited
// to the left side of the screen easily if required)
if (
duration < 1000 &&
Math.abs(direction[0]) > 30 && // swipe length to be detected
Math.abs(direction[0]) > Math.abs(direction[1] * 3) && // 30° should be "horizontal enough"
direction[0] > 0 // swipe left to right
Math.abs(direction[0]) > Math.abs(direction[1] * 3) // 30° should be "horizontal enough"
) {
this.toggleSideNav();
// definition of a "swipe right" gesture to move in the navigation
// only works in the far left edge of the screen
if (
direction[0] > 0 && // swipe left to right
this.swipeCoord[0] < 20
) {
this.sideNav.open();
}
// definition of a "swipe left" gesture to remove the navigation
// should only work in mobile mode to prevent unwanted closing of the nav
// works anywhere on the screen
if (
direction[0] < 0 && // swipe left to right
this.vp.isMobile
) {
this.sideNav.close();
}
}
}
}