Skip to content

Commit

Permalink
fix(layer-list): layer-list toolbar button were not linked to the lay…
Browse files Browse the repository at this point in the history
…ers status (#467)

* feat(layer) Visibility and resolution range now have an observable

* feat(layer-list) using visibility/range observable instead of set/get

* refactor(layer-list) Toolbar visible / in range  are disabled instead of hidden.

* refactor(layer-list) Better tooltip on toolbar

* feat(layer-list) detect changes on layers OR resolution

* lint

* feat(resolution): compute isInResolutionsRange on resolution change

* fix(layer-list toolbar) Resolution and visible status is now sync with layers.

* Update layer-list-binding.directive.ts

* Update layer.ts
  • Loading branch information
pelord authored and mbarbeau committed Nov 12, 2019
1 parent f2d25db commit d70eb0f
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { Directive, Self, OnInit, OnDestroy, AfterViewInit, Optional } from '@angular/core';
import { Subscription } from 'rxjs';
import { Subscription, combineLatest } from 'rxjs';

import { RouteService } from '@igo2/core';
import { MapService } from '../../map/shared/map.service';
import { LayerListComponent } from './layer-list.component';
import { LayerListService } from './layer-list.service';
import { Layer } from '../shared/layers/layer';
import { map, debounceTime } from 'rxjs/operators';

@Directive({
selector: '[igoLayerListBinding]'
})
export class LayerListBindingDirective implements OnInit, AfterViewInit, OnDestroy {
private component: LayerListComponent;
private layers$$: Subscription;
private layersOrResolutionChange$$: Subscription;
layersVisibility$$: Subscription;
layersRange$$: Subscription;

constructor(
@Self() component: LayerListComponent,
Expand All @@ -26,20 +29,46 @@ export class LayerListBindingDirective implements OnInit, AfterViewInit, OnDestr
ngOnInit() {
// Override input layers
this.component.layers = [];

this.layers$$ = this.mapService
.getMap()
.layers$.subscribe((layers: Layer[]) => {
this.component.layers = layers.filter((layer: Layer) => {
return layer.showInLayerList === true;
});
this.layersOrResolutionChange$$ = combineLatest([
this.mapService.getMap().layers$,
this.mapService.getMap().viewController.resolution$]
).pipe(
debounceTime(10)
).subscribe((bunch: [Layer[], number]) => {
const shownLayers = bunch[0].filter((layer: Layer) => {
return layer.showInLayerList === true;
});
this.component.layers = shownLayers;
this.setLayersVisibilityRangeStatus(shownLayers, this.component.excludeBaseLayers);
});
}

ngAfterViewInit(): void {
this.initRoutes();
}

private setLayersVisibilityRangeStatus(layers: Layer[], excludeBaseLayers: boolean) {
if (this.layersVisibility$$ !== undefined) {
this.layersVisibility$$.unsubscribe();
this.layersVisibility$$ = undefined;
}
if (this.layersRange$$ !== undefined) {
this.layersRange$$.unsubscribe();
this.layersRange$$ = undefined;
}
this.layersVisibility$$ = combineLatest(layers
.filter(layer => layer.baseLayer !== excludeBaseLayers )
.map((layer: Layer) => layer.visible$))
.pipe(map((visibles: boolean[]) => visibles.every(Boolean)))
.subscribe((allLayersAreVisible: boolean) =>
this.component.layersAreAllVisible = allLayersAreVisible);

this.layersRange$$ = combineLatest(layers.map((layer: Layer) => layer.isInResolutionsRange$))
.pipe(map((inrange: boolean[]) => inrange.every(Boolean)))
.subscribe((layersAreAllInRange: boolean) =>
this.component.layersAreAllInRange = layersAreAllInRange);
}

private initRoutes() {
if (
this.route &&
Expand All @@ -61,13 +90,13 @@ export class LayerListBindingDirective implements OnInit, AfterViewInit, OnDestr
}
if (onlyVisibleFromUrl &&
!this.layerListService.onlyVisibleInitialized &&
this.component.hasLayerNotVisible) {
!this.component.layersAreAllVisible) {
this.layerListService.onlyVisible = onlyVisibleFromUrl === '1' ? true : false;
this.layerListService.onlyVisibleInitialized = true;
}
if (onlyInRangeFromUrl &&
!this.layerListService.onlyInRangeInitialized &&
this.component.hasLayerOutOfRange) {
!this.component.layersAreAllInRange) {
this.layerListService.onlyInRange = onlyInRangeFromUrl === '1' ? true : false;
this.layerListService.onlyInRangeInitialized = true;
}
Expand All @@ -76,7 +105,15 @@ export class LayerListBindingDirective implements OnInit, AfterViewInit, OnDestr
}

ngOnDestroy() {
this.layers$$.unsubscribe();
this.layersOrResolutionChange$$.unsubscribe();
if (this.layersVisibility$$ !== undefined) {
this.layersVisibility$$.unsubscribe();
this.layersVisibility$$ = undefined;
}
if (this.layersRange$$ !== undefined) {
this.layersRange$$.unsubscribe();
this.layersRange$$ = undefined;
}
}

}
40 changes: 22 additions & 18 deletions packages/geo/src/lib/layer/layer-list/layer-list.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,32 @@
(click)="toggleSort(false)">
<mat-icon color="warn" svgIcon="sort-variant-remove"></mat-icon>
</button>
<button
mat-icon-button
[disabled]="!hasLayerNotVisible"
[matTooltip]="onlyVisible ?
<div [matTooltip]="onlyVisible ?
('igo.geo.layer.resetLayersList' | translate) :
('igo.geo.layer.subsetLayersListOnlyVisible' | translate)"
matTooltipShowDelay="500"
[color]="onlyVisible ? 'warn' : 'primary'"
(click)="toggleOnlyVisible()">
<mat-icon [svgIcon]="!onlyVisible ? 'eye' : 'sort-variant-remove'"></mat-icon>
</button>
<button
mat-icon-button
[disabled]="!hasLayerOutOfRange"
[matTooltip]="onlyInRange ?
matTooltipShowDelay="500">
<button
mat-icon-button
[disabled]="layersAreAllVisible && !onlyVisible"
[color]="onlyVisible ? 'warn' : 'primary'"
(click)="toggleOnlyVisible()">
<mat-icon
[svgIcon]="onlyVisible ? 'sort-variant-remove' : 'eye'"></mat-icon>
</button>
</div>
<div [matTooltip]="onlyInRange ?
('igo.geo.layer.resetLayersList' | translate) :
('igo.geo.layer.subsetLayersListOnlyInRange' | translate)"
matTooltipShowDelay="500"
[color]="onlyInRange ? 'warn' : 'primary'"
(click)="toggleOnlyInRange()">
<mat-icon [svgIcon]="!onlyInRange ? 'playlist-check' : 'sort-variant-remove'"></mat-icon>
</button>
matTooltipShowDelay="500">
<button
mat-icon-button
[disabled]="layersAreAllInRange && !onlyInRange"
[color]="onlyInRange ? 'warn' : 'primary'"
(click)="toggleOnlyInRange()">
<mat-icon
[svgIcon]="onlyInRange ? 'sort-variant-remove' : 'playlist-check'"></mat-icon>
</button>
</div>
</ng-container>
</mat-list-item>

Expand Down
29 changes: 7 additions & 22 deletions packages/geo/src/lib/layer/layer-list/layer-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush
})
export class LayerListComponent implements OnInit, OnDestroy {
hasLayerNotVisible = false;
hasLayerOutOfRange = false;
orderable = true;
thresholdToFilterAndSort = 5;

Expand All @@ -48,9 +46,13 @@ export class LayerListComponent implements OnInit, OnDestroy {

@ContentChild('igoLayerItemToolbar') templateLayerToolbar: TemplateRef<any>;

@Input() layersAreAllVisible: boolean = true;

@Input() layersAreAllInRange: boolean = true;

@Input()
set layers(value: Layer[]) {
this.setLayers(value);
this._layers = value;
this.next();
}
get layers(): Layer[] {
Expand Down Expand Up @@ -329,35 +331,18 @@ export class LayerListComponent implements OnInit, OnDestroy {
if (
this.layerFilterAndSortOptions.onlyVisible &&
!this.onlyVisibleInitialized &&
this.hasLayerNotVisible
!this.layersAreAllVisible
) {
this.onlyVisible = this.layerFilterAndSortOptions.onlyVisible;
this.onlyVisibleInitialized = true;
}
if (
this.layerFilterAndSortOptions.onlyInRange &&
!this.onlyInRangeInitialized &&
this.hasLayerOutOfRange
!this.layersAreAllInRange
) {
this.onlyInRange = this.layerFilterAndSortOptions.onlyInRange;
this.onlyInRangeInitialized = true;
}
}

private setLayers(layers: Layer[]) {
this._layers = layers;

if (this.excludeBaseLayers) {
this.hasLayerNotVisible =
layers.find(l => l.visible === false && !l.baseLayer) !== undefined;
this.hasLayerOutOfRange =
layers.find(l => l.isInResolutionsRange === false && !l.baseLayer) !==
undefined;
} else {
this.hasLayerNotVisible =
layers.find(l => l.visible === false) !== undefined;
this.hasLayerOutOfRange =
layers.find(l => l.isInResolutionsRange === false) !== undefined;
}
}
}
Loading

0 comments on commit d70eb0f

Please sign in to comment.