diff --git a/demo/src/app/geo/simple-map/simple-map.component.html b/demo/src/app/geo/simple-map/simple-map.component.html index e6cc05f1bc..0c1e08ac6c 100644 --- a/demo/src/app/geo/simple-map/simple-map.component.html +++ b/demo/src/app/geo/simple-map/simple-map.component.html @@ -18,6 +18,7 @@ + diff --git a/demo/src/app/geo/simple-map/simple-map.component.scss b/demo/src/app/geo/simple-map/simple-map.component.scss index 2f584dabc2..99e536b18b 100644 --- a/demo/src/app/geo/simple-map/simple-map.component.scss +++ b/demo/src/app/geo/simple-map/simple-map.component.scss @@ -1,4 +1,4 @@ igo-map-browser { width: 100%; - height: 300px; + height: 350px; } diff --git a/demo/src/environments/environment.ts b/demo/src/environments/environment.ts index 9afcfbed71..df1b32b5e8 100644 --- a/demo/src/environments/environment.ts +++ b/demo/src/environments/environment.ts @@ -12,6 +12,7 @@ interface Environment { export const environment: Environment = { production: false, igo: { + wakeLockApiButton: true, importWithStyle: true, projections: [ { diff --git a/package-lock.json b/package-lock.json index 8c95494b05..e92a68bb95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14449,6 +14449,11 @@ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true }, + "nosleep.js": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/nosleep.js/-/nosleep.js-0.12.0.tgz", + "integrity": "sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA==" + }, "now-and-later": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", diff --git a/package.json b/package.json index ad951e6470..70659fe0ce 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "moment": "^2.29.2", "ngx-color-picker": "^10.1.0", "ngx-toastr": "^14.1.3", + "nosleep.js": "^0.12.0", "ol": "^6.8.1", "ol-mapbox-style": "^6.5.1", "proj4": "^2.7.5", diff --git a/packages/geo/ng-package.json b/packages/geo/ng-package.json index b930efefc3..7608a3392d 100644 --- a/packages/geo/ng-package.json +++ b/packages/geo/ng-package.json @@ -6,6 +6,7 @@ "entryFile": "src/public_api.ts", "umdModuleIds": { "ngx-color-picker": "ngxColorPicker", + "nosleep.js": "NoSleep", "ol-mapbox-style/dist/stylefunction": "stylefunction", "ol/source/OSM": "olSourceOSM", "ol/source/XYZ": "olSourceXYZ", diff --git a/packages/geo/ng-package.prod.json b/packages/geo/ng-package.prod.json index 993f03dd67..8fc7f4c366 100644 --- a/packages/geo/ng-package.prod.json +++ b/packages/geo/ng-package.prod.json @@ -5,6 +5,7 @@ "entryFile": "src/public_api.ts", "umdModuleIds": { "ngx-color-picker": "ngxColorPicker", + "nosleep.js": "NoSleep", "ol-mapbox-style/dist/stylefunction": "stylefunction", "ol/source/OSM": "olSourceOSM", "ol/source/XYZ": "olSourceXYZ", diff --git a/packages/geo/package.json b/packages/geo/package.json index 3c327403df..60097f1d05 100644 --- a/packages/geo/package.json +++ b/packages/geo/package.json @@ -30,6 +30,7 @@ "@igo2/common": "^1.11.1", "@igo2/core": "^1.11.1", "@igo2/utils": "^1.11.1", + "nosleep.js": "^0.12.0", "ol": "^6.8.1", "proj4": "^2.7.5", "rxjs": "^6.6.7", diff --git a/packages/geo/src/lib/map/index.ts b/packages/geo/src/lib/map/index.ts index b3c4d8dd8b..73c93a0de0 100644 --- a/packages/geo/src/lib/map/index.ts +++ b/packages/geo/src/lib/map/index.ts @@ -6,6 +6,7 @@ export * from './menu-button'; export * from './geolocate-button'; export * from './home-extent-button'; export * from './offline-button'; +export * from './wake-lock-button'; export * from './baselayers-switcher'; export * from './rotation-button'; export * from './swipe-control'; diff --git a/packages/geo/src/lib/map/map-browser/map-browser.component.scss b/packages/geo/src/lib/map/map-browser/map-browser.component.scss index 52b1e56f7d..f27561668f 100644 --- a/packages/geo/src/lib/map/map-browser/map-browser.component.scss +++ b/packages/geo/src/lib/map/map-browser/map-browser.component.scss @@ -48,6 +48,15 @@ } } +:host ::ng-deep igo-wake-lock-button { + position: absolute; + top: calc(2 * #{$igo-icon-size} + 2 * 5px + #{$igo-margin}); + right: $igo-margin; + @include mobile { + bottom: calc(#{$igo-icon-size} + 5px + #{$igo-margin}); + } +} + :host ::ng-deep igo-home-extent-button { position: absolute; bottom: calc((3 * #{$igo-icon-size}) + 5px + (2 * #{$igo-margin})); diff --git a/packages/geo/src/lib/map/map.module.ts b/packages/geo/src/lib/map/map.module.ts index 09f621eebd..a4eb140de8 100644 --- a/packages/geo/src/lib/map/map.module.ts +++ b/packages/geo/src/lib/map/map.module.ts @@ -14,6 +14,7 @@ import { BaseLayersSwitcherComponent } from './baselayers-switcher/baselayers-sw import { MiniBaseMapComponent } from './baselayers-switcher/mini-basemap.component'; import { MapOfflineDirective } from './shared/mapOffline.directive'; import { OfflineButtonComponent } from './offline-button/offline-button.component'; +import { WakeLockButtonComponent } from './wake-lock-button/wake-lock-button.component'; import { PointerPositionDirective } from './shared/map-pointer-position.directive'; import { HoverFeatureDirective } from './shared/hover-feature.directive'; import { SwipeControlComponent } from './swipe-control/swipe-control.component'; @@ -41,6 +42,7 @@ import { InfoSectionComponent } from './info-section/info-section.component'; MiniBaseMapComponent, MapOfflineDirective, OfflineButtonComponent, + WakeLockButtonComponent, PointerPositionDirective, HoverFeatureDirective, SwipeControlComponent, @@ -58,6 +60,7 @@ import { InfoSectionComponent } from './info-section/info-section.component'; MiniBaseMapComponent, MapOfflineDirective, OfflineButtonComponent, + WakeLockButtonComponent, PointerPositionDirective, HoverFeatureDirective, SwipeControlComponent, diff --git a/packages/geo/src/lib/map/wake-lock-button/index.ts b/packages/geo/src/lib/map/wake-lock-button/index.ts new file mode 100644 index 0000000000..fb64522a94 --- /dev/null +++ b/packages/geo/src/lib/map/wake-lock-button/index.ts @@ -0,0 +1 @@ +export * from './wake-lock-button.component'; diff --git a/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.html b/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.html new file mode 100644 index 0000000000..cc17d4ea31 --- /dev/null +++ b/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.html @@ -0,0 +1,12 @@ +
+
+ +
+
\ No newline at end of file diff --git a/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.scss b/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.scss new file mode 100644 index 0000000000..d376558e96 --- /dev/null +++ b/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.scss @@ -0,0 +1,14 @@ +@import '../../../../../core/src/style/partial/core.variables'; + +.igo-wake-lock-button-container { + width: $igo-icon-size; + background-color: #fff; + &:hover { + background-color: #efefef; + } +} + +button, +:host ::ng-deep button .mat-button-ripple-round { + border-radius: 0; +} diff --git a/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.ts b/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.ts new file mode 100644 index 0000000000..be69fa95ca --- /dev/null +++ b/packages/geo/src/lib/map/wake-lock-button/wake-lock-button.component.ts @@ -0,0 +1,91 @@ +import { Component, Input } from '@angular/core'; +import { ConfigService, StorageService } from '@igo2/core'; +import { BehaviorSubject } from 'rxjs'; +import NoSleep from 'nosleep.js'; +import { IgoMap } from '../shared/map'; +import { userAgent } from '@igo2/utils'; + +@Component({ + selector: 'igo-wake-lock-button', + templateUrl: './wake-lock-button.component.html', + styleUrls: ['./wake-lock-button.component.scss'] +}) + +/** + * Prevent display sleep and enable wake lock in all Android and iOS web browsers. + * On iOS, the Wake Lock API is not supported + * https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API + * On not supported browser, a fake video is used to keep the screen open. + * + * TODO: When the API will be supported by every browser, We should remove the NoSleep.js dependency + * and replace it by a WakeLock API implementation. + */ +export class WakeLockButtonComponent { + + @Input() color: string = 'primary'; + @Input() map: IgoMap; + @Input() + get enabled(): boolean { + return this.storageService.get('wakeLockEnabled') as boolean; + } + set enabled(value: boolean) { + this.storageService.set('wakeLockEnabled', value); + } + + private noSleep: NoSleep; + readonly icon$: BehaviorSubject = new BehaviorSubject('sleep'); + public visible = false; + + constructor( + private config: ConfigService, + private storageService: StorageService + ) { + this.visible = this.config.getConfig('wakeLockApiButton') ? true : false; + this.noSleep = new NoSleep(); + const nonWakeLockApiBrowser = userAgent.satisfies({ + ie: '>0', + edge: '<84', + chrome: '<84', + firefox: '>0', + opera: '<70', + safari: '>0' + }); + if (nonWakeLockApiBrowser) { + this.disableWakeLock(); + this.enabled = false; + window.onblur = () => { + this.disableWakeLock(); + this.enabled = false; + }; + } + this.enabled ? this.enableWakeLock() : this.disableWakeLock(); + } + + /** + * Prevent display sleep and enable wake lock in all Android and iOS web browsers. + * On iOS, the Wake Lock API is not supported + * https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API + * On not supported browser, a fake video is used to keep the screen open. + */ + private enableWakeLock() { + this.noSleep.enable(); + this.enabled = true; + this.icon$.next('sleep-off'); + } + /** + * Let display sleep + */ + private disableWakeLock() { + this.noSleep.disable(); + this.enabled = false; + this.icon$.next('sleep'); + } + + toggleWakeLock() { + if (this.enabled) { + this.disableWakeLock(); + } else { + this.enableWakeLock(); + } + } +} diff --git a/packages/geo/src/locale/en.geo.json b/packages/geo/src/locale/en.geo.json index c01af16a55..38debfaf05 100644 --- a/packages/geo/src/locale/en.geo.json +++ b/packages/geo/src/locale/en.geo.json @@ -272,7 +272,9 @@ "zoomIn": "Zoom in ({{zoom}})", "zoomOut": "Zoom out ({{zoom}})", "resetRotation": "Set map to north", - "tipRotation": "Hold Alt and SHIFT while dragging on map to rotate the map." + "tipRotation": "Hold Alt and SHIFT while dragging on map to rotate the map.", + "preventSreenLock": "Prevent the screen to enter in lock mode.", + "letScreenLock": "Allow the screen to enter in lock mode." }, "metadata": { "show": "Show metadata" diff --git a/packages/geo/src/locale/fr.geo.json b/packages/geo/src/locale/fr.geo.json index f068b1b18f..5598a46a84 100644 --- a/packages/geo/src/locale/fr.geo.json +++ b/packages/geo/src/locale/fr.geo.json @@ -271,7 +271,9 @@ "zoomIn": "Zoomer ({{zoom}})", "zoomOut": "Dézoomer ({{zoom}})", "resetRotation": "Réinitialiser la carte vers le nord", - "tipRotation": "Maintenez les touches Alt et Majuscule (shift) tout en cliquant sur la carte pour faire pivoter la carte" + "tipRotation": "Maintenez les touches Alt et Majuscule (shift) tout en cliquant sur la carte pour faire pivoter la carte", + "preventSreenLock": "Prévient l'écran d'entrer en mode verrouillé.", + "letScreenLock": "Permet l'écran d'entrer en mode verrouillé." }, "metadata": { "show": "Montrer les métadonnées"