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:
parent
798af8c5ab
commit
0ceddd2662
@ -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
|
||||
*/
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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">
|
||||
|
@ -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,11 +1079,13 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
||||
* @param motion target
|
||||
*/
|
||||
public navigateToMotion(motion: ViewMotion): void {
|
||||
if (motion) {
|
||||
this.router.navigate(['../' + motion.id], { relativeTo: this.route });
|
||||
// update the current motion
|
||||
this.motion = motion;
|
||||
this.setSurroundingMotions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the previous and next motion. Sorts ascending by identifier, and
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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'"
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user