Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(map): new button to manually activate/deactivate offline mode #539

Merged
merged 18 commits into from
Dec 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/geo/src/lib/map/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export * from './shared';
export * from './map-browser';
export * from './zoom-button';
export * from './geolocate-button';
export * from './offline-button';
export * from './baselayers-switcher';
export * from './rotation-button';
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
}
}

:host >>> igo-offline-button {
position: absolute;
bottom:15px;
right: $igo-margin;
@include mobile {
bottom: $igo-margin;
}
}

:host >>> igo-geolocate-button {
position: absolute;
bottom: 5px;
Expand Down
3 changes: 3 additions & 0 deletions packages/geo/src/lib/map/map.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { RotationButtonComponent } from './rotation-button/rotation-button.compo
import { BaseLayersSwitcherComponent } from './baselayers-switcher/baselayers-switcher.component';
import { MiniBaseMapComponent } from './baselayers-switcher/mini-basemap.component';
import { MapOfflineDirective } from './shared/mapOffline.directive';
import { OfflineButtonComponent } from './offline-button/offline-button.component';
import { PointerPositionDirective } from './shared/map-pointer-position.directive';
import { PointerPositionByKeyDirective } from './shared/map-pointer-position-by-key.directive';

Expand All @@ -37,6 +38,7 @@ import { PointerPositionByKeyDirective } from './shared/map-pointer-position-by-
BaseLayersSwitcherComponent,
MiniBaseMapComponent,
MapOfflineDirective,
OfflineButtonComponent,
PointerPositionDirective,
PointerPositionByKeyDirective
],
Expand All @@ -48,6 +50,7 @@ import { PointerPositionByKeyDirective } from './shared/map-pointer-position-by-
BaseLayersSwitcherComponent,
MiniBaseMapComponent,
MapOfflineDirective,
OfflineButtonComponent,
PointerPositionDirective,
PointerPositionByKeyDirective
]
Expand Down
1 change: 1 addition & 0 deletions packages/geo/src/lib/map/offline-button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './offline-button.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div *ngIf="visible" class="igo-user-button-container">
<div>
<button
mat-icon-button
[matTooltip]="checked ? ('igo.geo.mapButtons.online' | translate): ('igo.geo.mapButtons.offline' | translate)"
matTooltipPosition="left"
[ngClass]="[btnStyle]"
[color]="checked ? color : [colorOff]"
(click)="onToggle()"
(click)="map.onOfflineToggle(check)">
<mat-icon svgIcon="wifi-strength-off"></mat-icon>
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@import '../../../../../core/src/style/partial/media';
@import '../../../../../core/src/style/partial/core.variables';

.baseStyle {
width: $igo-icon-size;
background-color: rgb(255, 255, 255);
&:hover {
background-color: #efefef;
}
}

.toggleStyle {
width: $igo-icon-size;
background-color: #b9b9b9;
}

button,
:host >>> button .mat-button-ripple-round {
border-radius: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Component, Input, EventEmitter, Output, AfterViewInit } from '@angular/core';
import { IgoMap } from '../shared/map';
import { Observable, BehaviorSubject, Subscription, fromEvent } from 'rxjs';
import { debounceTime, startWith } from 'rxjs/operators';
import { ConfigService } from '@igo2/core';

@Component({
selector: 'igo-offline-button',
templateUrl: './offline-button.component.html',
styleUrls: ['./offline-button.component.scss']
})

export class OfflineButtonComponent {

btnStyle: string = 'baseStyle';
colorOff: string = 'rgb(255,255,255)';

@Output() change = new EventEmitter<boolean>();

@Input()
get map(): IgoMap {
return this._map;
}
set map(value: IgoMap) {
this._map = value;
}
private _map: IgoMap;

@Input()
get color(): string {
return this._color;
}
set color(value: string) {
this._color = value;
}
private _color: string;

@Input() public check: boolean = false;

get checked(): boolean {
return this.check;
}

public visible = false;

constructor(
private config: ConfigService
) {
this.visible = this.config.getConfig('offlineButton') ? true : false;
}

onToggle() {
this.check = !this.check;
if (this.check) {
this.btnStyle = 'toggleStyle';
} else {
this.btnStyle = 'baseStyle';
}
}
}
5 changes: 5 additions & 0 deletions packages/geo/src/lib/map/shared/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { FeatureDataSource } from '../../datasource/shared/datasources/feature-d
// Move some stuff into controllers.
export class IgoMap {
public ol: olMap;
public offlineButtonToggle$ = new BehaviorSubject<boolean>(false);
public layers$ = new BehaviorSubject<Layer[]>([]);
public status$: Subject<SubjectStatus>;
public geolocation$ = new BehaviorSubject<olGeolocation>(undefined);
Expand Down Expand Up @@ -456,4 +457,8 @@ export class IgoMap {
this.geolocation.setTracking(false);
}
}

onOfflineToggle(offline: boolean) {
this.offlineButtonToggle$.next(offline);
}
}
83 changes: 63 additions & 20 deletions packages/geo/src/lib/map/shared/mapOffline.directive.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,85 @@
import { Directive, AfterViewInit } from '@angular/core';
import { NetworkService, ConnectionState } from '@igo2/core';
import { NetworkService, ConnectionState, MessageService, LanguageService } from '@igo2/core';

import { IgoMap } from './map';
import { MapBrowserComponent } from '../map-browser/map-browser.component';
import { FeatureDataSourceOptions } from '../../datasource/shared/datasources/feature-datasource.interface';
import { XYZDataSourceOptions } from '../../datasource/shared/datasources/xyz-datasource.interface';
import { MVTDataSourceOptions } from '../../datasource/shared/datasources/mvt-datasource.interface';
import { ClusterDataSourceOptions } from '../../datasource/shared/datasources/cluster-datasource.interface';
import { Layer } from '../../layer/shared/layers/layer';

@Directive({
selector: '[igoMapOffline]'
})
export class MapOfflineDirective implements AfterViewInit {

private state: ConnectionState;
private component: MapBrowserComponent;
private offlineButtonStatus: boolean = false;
private networkState: ConnectionState = {
connection: true
};
private offlineButtonState: ConnectionState = {
connection: true
};

get map(): IgoMap {
return this.component.map;
}

constructor(
component: MapBrowserComponent,
private networkService: NetworkService
private networkService: NetworkService,
private messageService: MessageService,
private languageService: LanguageService
) {
this.component = component;
}

ngAfterViewInit() {
this.networkService.currentState().subscribe((state: ConnectionState) => {
this.state = state;
this.changeLayer();
});
ngAfterViewInit() {
this.map.offlineButtonToggle$.subscribe((offlineButtonToggle: boolean) => {
this.offlineButtonStatus = offlineButtonToggle;
const translate = this.languageService.translate;
if (this.offlineButtonStatus && this.networkState.connection) {
const message = translate.instant('igo.geo.network.offline.message');
const title = translate.instant('igo.geo.network.offline.title');
this.messageService.info(message, title);
this.offlineButtonState.connection = false;
this.changeLayer();
} else if (!this.offlineButtonStatus && !this.networkState.connection) {
const message = translate.instant('igo.geo.network.offline.message');
const title = translate.instant('igo.geo.network.offline.title');
this.messageService.info(message, title);
this.offlineButtonState.connection = false;
this.changeLayer();
} else if (!this.offlineButtonStatus && this.networkState.connection) {
let message;
let title;
const messageObs = translate.get('igo.geo.network.online.message');
const titleObs = translate.get('igo.geo.network.online.title');
messageObs.subscribe((message1: string) => {
message = message1;
});
titleObs.subscribe((title1: string) => {
title = title1;
});
this.messageService.info(message, title);
this.offlineButtonState.connection = true;
this.changeLayer();
}
});

this.map.layers$.subscribe(() => {
this.changeLayer();
});
}
this.networkService.currentState().subscribe((state: ConnectionState) => {
this.networkState = state;
if (!this.offlineButtonStatus) {
this.changeLayer();
}
});

this.map.layers$.subscribe((layers: Layer[]) => {
this.changeLayer();
});
}

private changeLayer() {
let sourceOptions;
Expand All @@ -52,31 +95,31 @@ export class MapOfflineDirective implements AfterViewInit {
} else if (layer.options.sourceOptions.type === 'cluster') {
sourceOptions = (layer.options.sourceOptions as ClusterDataSourceOptions);
} else {
if (this.state.connection === false) {
if (this.networkState.connection === false || this.offlineButtonState.connection === false) {
layer.ol.setMaxResolution(0);
return;
} else if (this.state.connection === true) {
} else if (this.networkState.connection === true || this.offlineButtonState.connection === true) {
layer.ol.setMaxResolution(Infinity);
return;
}
}

if (sourceOptions.pathOffline &&
this.state.connection === false) {
if (sourceOptions.pathOffline && this.networkState.connection === false ||
sourceOptions.pathOffline && this.offlineButtonState.connection === false) {
if (sourceOptions.type === 'vector' || sourceOptions.type === 'cluster') {
return;
}
layer.ol.getSource().setUrl(sourceOptions.pathOffline);
} else if (sourceOptions.pathOffline &&
this.state.connection === true) {
} else if (sourceOptions.pathOffline && this.networkState.connection === false ||
sourceOptions.pathOffline && this.offlineButtonState.connection === true) {
if (sourceOptions.type === 'vector' || sourceOptions.type === 'cluster') {
return;
}
layer.ol.getSource().setUrl(sourceOptions.url);
} else {
if (this.state.connection === false) {
if (this.networkState.connection === false || this.offlineButtonState.connection === false) {
layer.ol.setMaxResolution(0);
} else if (this.state.connection === true) {
} else if (this.networkState.connection === true || this.offlineButtonState.connection === true) {
layer.ol.setMaxResolution(Infinity);
}
}
Expand Down
12 changes: 12 additions & 0 deletions packages/geo/src/locale/en.geo.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@
"mapButtons": {
"baselayerSwitcher": "Change base layer",
"geolocate": "Geolocate",
"offline": "Offline mode",
"online": "Online mode",
"zoomIn": "Zoom in ({{zoom}})",
"zoomOut": "Zoom out ({{zoom}})",
"resetRotation": "Set map to north",
Expand Down Expand Up @@ -396,6 +398,16 @@
"ogcFilter.tooltip": "Apply filters",
"wfsDownload.title": "Download",
"wfsDownload.tooltip": "Download"
},
"network": {
"online": {
"message": "Online",
"title": "Status:"
},
"offline": {
"message": "Offline",
"title": "Status:"
}
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions packages/geo/src/locale/fr.geo.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@
"mapButtons": {
"baselayerSwitcher": "Changer le fond de carte",
"geolocate": "Afficher votre position",
"offline": "Passer en mode hors-ligne",
"online": "Passer en mode en ligne",
"zoomIn": "Zoomer ({{zoom}})",
"zoomOut": "Dézoomer ({{zoom}})",
"resetRotation": "Réinitialiser la carte vers le nord",
Expand Down Expand Up @@ -397,6 +399,16 @@
"ogcFilter.tooltip": "Appliquer des filtres sur la couche",
"wfsDownload.title": "Télécharger les données associées",
"wfsDownload.tooltip": "Télécharger les données associées"
},
"network": {
"online": {
"message": "En ligne",
"title": "Statut:"
},
"offline": {
"message": "Hors-Ligne",
"title": "Statut:"
}
}
}
}
Expand Down