Merge pull request #4410 from tsiegleauq/more-swipe-gestures
Add swipe gestures into motion detail
This commit is contained in:
commit
0dd2dcc352
@ -17,6 +17,16 @@ export abstract class BaseComponent {
|
|||||||
*/
|
*/
|
||||||
private titleSuffix = ' - OpenSlides';
|
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
|
* 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
|
* automatically dismisses the error snack bar and clears subscriptions
|
||||||
* if the component is destroyed.
|
* if the component is destroyed.
|
||||||
|
@ -60,7 +60,9 @@ export abstract class ListViewBaseComponent<V extends BaseViewModel, M extends B
|
|||||||
* Constructor for list view bases
|
* Constructor for list view bases
|
||||||
* @param titleService the title serivce
|
* @param titleService the title serivce
|
||||||
* @param translate the translate service
|
* @param translate the translate service
|
||||||
* @param matSnackBar
|
* @param matSnackBar showing errors
|
||||||
|
* @param filterService filter
|
||||||
|
* @param sortService sorting
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
titleService: Title,
|
titleService: Title,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Back and forth buttons -->
|
<!-- 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">
|
<div *ngIf="previousMotion">
|
||||||
<button mat-button (click)="navigateToMotion(previousMotion)">
|
<button mat-button (click)="navigateToMotion(previousMotion)">
|
||||||
<!-- possible icons:
|
<!-- possible icons:
|
||||||
@ -103,7 +103,7 @@
|
|||||||
</mat-menu>
|
</mat-menu>
|
||||||
</os-head-bar>
|
</os-head-bar>
|
||||||
|
|
||||||
<div class="content-container">
|
<div class="content-container" (touchstart)="swipe($event, 'start')" (touchend)="swipe($event, 'end')">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div class="title on-transition-fade" *ngIf="motion && !editMotion">
|
<div class="title on-transition-fade" *ngIf="motion && !editMotion">
|
||||||
<div class="title-line">
|
<div class="title-line">
|
||||||
|
@ -28,6 +28,7 @@ import {
|
|||||||
} from '../motion-change-recommendation/motion-change-recommendation.component';
|
} from '../motion-change-recommendation/motion-change-recommendation.component';
|
||||||
import { MotionPdfExportService } from '../../services/motion-pdf-export.service';
|
import { MotionPdfExportService } from '../../services/motion-pdf-export.service';
|
||||||
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
||||||
|
|
||||||
import { NotifyService } from 'app/core/core-services/notify.service';
|
import { NotifyService } from 'app/core/core-services/notify.service';
|
||||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||||
import { PersonalNoteContent } from 'app/shared/models/users/personal-note';
|
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 { ViewStatuteParagraph } from '../../models/view-statute-paragraph';
|
||||||
import { ViewTag } from 'app/site/tags/models/view-tag';
|
import { ViewTag } from 'app/site/tags/models/view-tag';
|
||||||
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change';
|
import { ViewUnifiedChange } from 'app/shared/models/motions/view-unified-change';
|
||||||
|
|
||||||
import { Workflow } from 'app/shared/models/motions/workflow';
|
import { Workflow } from 'app/shared/models/motions/workflow';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1079,11 +1079,13 @@ export class MotionDetailComponent extends BaseViewComponent implements OnInit,
|
|||||||
* @param motion target
|
* @param motion target
|
||||||
*/
|
*/
|
||||||
public navigateToMotion(motion: ViewMotion): void {
|
public navigateToMotion(motion: ViewMotion): void {
|
||||||
|
if (motion) {
|
||||||
this.router.navigate(['../' + motion.id], { relativeTo: this.route });
|
this.router.navigate(['../' + motion.id], { relativeTo: this.route });
|
||||||
// update the current motion
|
// update the current motion
|
||||||
this.motion = motion;
|
this.motion = motion;
|
||||||
this.setSurroundingMotions();
|
this.setSurroundingMotions();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the previous and next motion. Sorts ascending by identifier, and
|
* 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] || '';
|
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>
|
<span>({{ getHistoryTimestamp() }})</span>
|
||||||
<a (click)="timeTravel.resumeTime()" translate>Exit</a>
|
<a (click)="timeTravel.resumeTime()" translate>Exit</a>
|
||||||
</div>
|
</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
|
<mat-sidenav
|
||||||
#sideNav
|
#sideNav
|
||||||
[mode]="vp.isMobile ? 'over' : 'side'"
|
[mode]="vp.isMobile ? 'over' : 'side'"
|
||||||
|
@ -38,16 +38,6 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public isLoggedIn: boolean;
|
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.
|
* Holds the typed search query.
|
||||||
*/
|
*/
|
||||||
@ -171,18 +161,29 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
|||||||
} else if (when === 'end') {
|
} else if (when === 'end') {
|
||||||
const direction = [coord[0] - this.swipeCoord[0], coord[1] - this.swipeCoord[1]];
|
const direction = [coord[0] - this.swipeCoord[0], coord[1] - this.swipeCoord[1]];
|
||||||
const duration = time - this.swipeTime;
|
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 (
|
if (
|
||||||
duration < 1000 &&
|
duration < 1000 &&
|
||||||
Math.abs(direction[0]) > 30 && // swipe length to be detected
|
Math.abs(direction[0]) > 30 && // swipe length to be detected
|
||||||
Math.abs(direction[0]) > Math.abs(direction[1] * 3) && // 30° should be "horizontal enough"
|
Math.abs(direction[0]) > Math.abs(direction[1] * 3) // 30° should be "horizontal enough"
|
||||||
direction[0] > 0 // swipe left to right
|
|
||||||
) {
|
) {
|
||||||
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