diff --git a/src/components.d.ts b/src/components.d.ts index 757f2dd9..2b249446 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -5,8 +5,8 @@ * It contains typing information for all components that exist in this project. */ import { HTMLStencilElement, JSXBase } from "@stencil/core/internal"; -import { InformationDesk, OutdoorCourse, OutdoorSite, Poi, SensitiveArea, TouristicContent, TouristicEvent, Trek } from "./types/types"; -export { InformationDesk, OutdoorCourse, OutdoorSite, Poi, SensitiveArea, TouristicContent, TouristicEvent, Trek } from "./types/types"; +import { InformationDesk, Mode, OutdoorCourse, OutdoorSite, Poi, SensitiveArea, TouristicContent, TouristicEvent, Trek } from "./types/types"; +export { InformationDesk, Mode, OutdoorCourse, OutdoorSite, Poi, SensitiveArea, TouristicContent, TouristicEvent, Trek } from "./types/types"; export namespace Components { interface GrwApp { "api": string; @@ -113,6 +113,9 @@ export namespace Components { "urlLayer": string; "useGradient": boolean; } + interface GrwOfflineConfirmModal { + "mode": Mode; + } interface GrwOutdoorCourseCard { "colorOnSecondaryContainer": string; "colorOnSurface": string; @@ -389,10 +392,6 @@ export namespace Components { "themes": string; } } -export interface GrwAppCustomEvent extends CustomEvent { - detail: T; - target: HTMLGrwAppElement; -} export interface GrwFiltersCustomEvent extends CustomEvent { detail: T; target: HTMLGrwFiltersElement; @@ -405,6 +404,10 @@ export interface GrwMapCustomEvent extends CustomEvent { detail: T; target: HTMLGrwMapElement; } +export interface GrwOfflineConfirmModalCustomEvent extends CustomEvent { + detail: T; + target: HTMLGrwOfflineConfirmModalElement; +} export interface GrwOutdoorCourseCardCustomEvent extends CustomEvent { detail: T; target: HTMLGrwOutdoorCourseCardElement; @@ -438,19 +441,7 @@ export interface GrwTrekDetailCustomEvent extends CustomEvent { target: HTMLGrwTrekDetailElement; } declare global { - interface HTMLGrwAppElementEventMap { - "downloadPress": number; - "deletePress": number; - } interface HTMLGrwAppElement extends Components.GrwApp, HTMLStencilElement { - addEventListener(type: K, listener: (this: HTMLGrwAppElement, ev: GrwAppCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; - addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLGrwAppElement, ev: GrwAppCustomEvent) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; - removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLGrwAppElement: { prototype: HTMLGrwAppElement; @@ -535,6 +526,24 @@ declare global { prototype: HTMLGrwMapElement; new (): HTMLGrwMapElement; }; + interface HTMLGrwOfflineConfirmModalElementEventMap { + "downloadPress": number; + "deletePress": number; + } + interface HTMLGrwOfflineConfirmModalElement extends Components.GrwOfflineConfirmModal, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLGrwOfflineConfirmModalElement, ev: GrwOfflineConfirmModalCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLGrwOfflineConfirmModalElement, ev: GrwOfflineConfirmModalCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; + } + var HTMLGrwOfflineConfirmModalElement: { + prototype: HTMLGrwOfflineConfirmModalElement; + new (): HTMLGrwOfflineConfirmModalElement; + }; interface HTMLGrwOutdoorCourseCardElementEventMap { "outdoorCourseCardPress": number; "cardOutdoorCourseMouseOver": number; @@ -845,6 +854,7 @@ declare global { "grw-information-desk": HTMLGrwInformationDeskElement; "grw-loader": HTMLGrwLoaderElement; "grw-map": HTMLGrwMapElement; + "grw-offline-confirm-modal": HTMLGrwOfflineConfirmModalElement; "grw-outdoor-course-card": HTMLGrwOutdoorCourseCardElement; "grw-outdoor-course-detail": HTMLGrwOutdoorCourseDetailElement; "grw-outdoor-course-provider": HTMLGrwOutdoorCourseProviderElement; @@ -915,8 +925,6 @@ declare namespace LocalJSX { "labels"?: string; "languages"?: string; "nameLayer"?: string; - "onDeletePress"?: (event: GrwAppCustomEvent) => void; - "onDownloadPress"?: (event: GrwAppCustomEvent) => void; "outdoor"?: boolean; "portals"?: string; "practices"?: string; @@ -992,6 +1000,11 @@ declare namespace LocalJSX { "urlLayer"?: string; "useGradient"?: boolean; } + interface GrwOfflineConfirmModal { + "mode"?: Mode; + "onDeletePress"?: (event: GrwOfflineConfirmModalCustomEvent) => void; + "onDownloadPress"?: (event: GrwOfflineConfirmModalCustomEvent) => void; + } interface GrwOutdoorCourseCard { "colorOnSecondaryContainer"?: string; "colorOnSurface"?: string; @@ -1317,6 +1330,7 @@ declare namespace LocalJSX { "grw-information-desk": GrwInformationDesk; "grw-loader": GrwLoader; "grw-map": GrwMap; + "grw-offline-confirm-modal": GrwOfflineConfirmModal; "grw-outdoor-course-card": GrwOutdoorCourseCard; "grw-outdoor-course-detail": GrwOutdoorCourseDetail; "grw-outdoor-course-provider": GrwOutdoorCourseProvider; @@ -1361,6 +1375,7 @@ declare module "@stencil/core" { "grw-information-desk": LocalJSX.GrwInformationDesk & JSXBase.HTMLAttributes; "grw-loader": LocalJSX.GrwLoader & JSXBase.HTMLAttributes; "grw-map": LocalJSX.GrwMap & JSXBase.HTMLAttributes; + "grw-offline-confirm-modal": LocalJSX.GrwOfflineConfirmModal & JSXBase.HTMLAttributes; "grw-outdoor-course-card": LocalJSX.GrwOutdoorCourseCard & JSXBase.HTMLAttributes; "grw-outdoor-course-detail": LocalJSX.GrwOutdoorCourseDetail & JSXBase.HTMLAttributes; "grw-outdoor-course-provider": LocalJSX.GrwOutdoorCourseProvider & JSXBase.HTMLAttributes; diff --git a/src/components/grw-app/grw-app.scss b/src/components/grw-app/grw-app.scss index c168da1d..68a67f20 100644 --- a/src/components/grw-app/grw-app.scss +++ b/src/components/grw-app/grw-app.scss @@ -199,84 +199,6 @@ grw-outdoor-site-detail { } } -.modal-container { - z-index: 40000; - position: absolute; - display: flex; - align-items: center; - justify-content: center; - font-family: var(--font-family); - top: -64px; - left: 0px; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.6); - - .modal-content-container { - display: flex; - justify-content: center; - flex-direction: column; - width: 380px; - height: 120px; - padding: 16px; - margin: 0px 16px; - background-color: var(--color-background); - border-radius: var(--border-radius, 8px); - } - - .modal-message-container { - display: flex; - align-items: center; - justify-content: center; - - .modal-loader { - width: 16px; - height: 16px; - border: 3px solid var(--color-primary-container); - border-bottom-color: var(--color-on-primary-container); - border-radius: 50%; - display: inline-block; - box-sizing: border-box; - animation: rotation 1s linear infinite; - margin-right: 16px; - } - - @keyframes rotation { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } - } - } - - .modal-buttons-container, - .modal-button-container { - display: flex; - align-items: center; - justify-content: space-between; - margin-top: 16px; - .modal-button { - cursor: pointer; - user-select: none; - font-size: 14px; - font-weight: 500; - height: 32px; - box-shadow: var(--elevation-0); - border: none; - -webkit-tap-highlight-color: transparent; - line-height: 20px; - color: var(--color-primary-app); - background-color: transparent; - font-family: var(--font-family); - } - } - .modal-button-container { - justify-content: flex-end; - } -} - .grw-offline-container { display: flex; align-items: center; diff --git a/src/components/grw-app/grw-app.tsx b/src/components/grw-app/grw-app.tsx index 1db35c62..39bf99d9 100644 --- a/src/components/grw-app/grw-app.tsx +++ b/src/components/grw-app/grw-app.tsx @@ -1,5 +1,5 @@ import { Capacitor } from '@capacitor/core'; -import { Component, Host, h, Listen, State, Prop, Element, Watch, Event, EventEmitter, Fragment } from '@stencil/core'; +import { Component, Host, h, Listen, State, Prop, Element, Watch, Fragment } from '@stencil/core'; import { translate } from 'i18n/i18n'; import state, { reset } from 'store/store'; import { handleOutdoorSitesFiltersAndSearch, handleTreksFiltersAndSearch, imagesRegExp, revokeObjectURL } from 'utils/utils'; @@ -89,17 +89,6 @@ export class GrwApp { @Prop() tilesMinZoomOffline = 12; @Prop() tilesMaxZoomOffline = 16; - @State() showOfflineModal = false; - @State() showConfirmModal = false; - @State() showLoaderModal = false; - @State() showSuccessModal = false; - @State() showConfirmDeleteModal = false; - @State() showDeletingMessage = false; - @State() showDeleteSuccessMessage = false; - - @Event() downloadPress: EventEmitter; - @Event() deletePress: EventEmitter; - largeViewSize = 1024; handlePopStateBind: (event: any) => void = this.handlePopState.bind(this); @@ -222,40 +211,6 @@ export class GrwApp { } } - @Listen('downloadConfirm', { target: 'window' }) - onDownloadConfirm() { - this.showLoaderModal = false; - this.showSuccessModal = false; - this.showDeleteSuccessMessage = false; - this.showDeletingMessage = false; - this.showConfirmDeleteModal = false; - this.showOfflineModal = true; - this.showConfirmModal = true; - } - - @Listen('downloadedSuccessConfirm', { target: 'window' }) - onDownloadedSuccessConfirm() { - this.showLoaderModal = false; - this.showSuccessModal = true; - } - - @Listen('deleteConfirm', { target: 'window' }) - onDeleteConfirm() { - this.showLoaderModal = false; - this.showSuccessModal = false; - this.showDeleteSuccessMessage = false; - this.showOfflineModal = true; - this.showConfirmModal = true; - this.showConfirmDeleteModal = true; - } - - @Listen('deleteSuccessConfirm', { target: 'window' }) - onDeleteSuccessConfirm() { - this.showLoaderModal = false; - this.showSuccessModal = true; - this.showDeleteSuccessMessage = true; - } - @Watch('isLargeView') watchPropHandler() { window.dispatchEvent(new window.Event('resize')); @@ -463,24 +418,6 @@ export class GrwApp { window.removeEventListener('popstate', this.handlePopStateBind); } - handleOkDeleteModal() { - this.showDeletingMessage = true; - this.showConfirmDeleteModal = false; - this.showConfirmModal = false; - this.showLoaderModal = true; - this.deletePress.emit(); - } - - handleOkDownloadModal() { - this.showConfirmModal = false; - this.showLoaderModal = true; - this.downloadPress.emit(); - } - - handleCancelModal() { - this.showOfflineModal = false; - } - handleOffline() { if (state.mode === 'treks') { state.offlineTreks = !state.offlineTreks; @@ -834,64 +771,7 @@ export class GrwApp { tiles-max-zoom-offline={this.tilesMaxZoomOffline} grw-app={true} > - {this.showOfflineModal && ( - - )} + )} {this.showTouristicContent && state.currentTouristicContent && ( @@ -956,64 +836,7 @@ export class GrwApp { default-background-layer-attribution={this.attributionLayer ? this.attributionLayer.split(',')[0] : []} enable-offline={this.enableOffline} > - {this.showOfflineModal && ( - - )} + )} {this.showOutdoorCourse && state.currentOutdoorCourse && ( diff --git a/src/components/grw-app/readme.md b/src/components/grw-app/readme.md index 79075590..f596a4e7 100644 --- a/src/components/grw-app/readme.md +++ b/src/components/grw-app/readme.md @@ -60,21 +60,12 @@ | `weather` | `weather` | | `boolean` | `false` | -## Events - -| Event | Description | Type | -| --------------- | ----------- | --------------------- | -| `deletePress` | | `CustomEvent` | -| `downloadPress` | | `CustomEvent` | - - ## Shadow Parts | Part | Description | | ------------------------- | ----------- | | `"grw-offline-container"` | | | `"icon"` | | -| `"modal-button"` | | ## Dependencies @@ -101,6 +92,7 @@ - [grw-touristic-events-list](../grw-touristic-events-list) - [grw-outdoor-sites-list](../grw-outdoor-sites-list) - [grw-trek-detail](../grw-trek-detail) +- [grw-offline-confirm-modal](../grw-offline-confirm-modal) - [grw-touristic-content-detail](../grw-touristic-content-detail) - [grw-touristic-event-detail](../grw-touristic-event-detail) - [grw-outdoor-site-detail](../grw-outdoor-site-detail) @@ -132,6 +124,7 @@ graph TD; grw-app --> grw-touristic-events-list grw-app --> grw-outdoor-sites-list grw-app --> grw-trek-detail + grw-app --> grw-offline-confirm-modal grw-app --> grw-touristic-content-detail grw-app --> grw-touristic-event-detail grw-app --> grw-outdoor-site-detail diff --git a/src/components/grw-offline-confirm-modal/grw-offline-confirm-modal.scss b/src/components/grw-offline-confirm-modal/grw-offline-confirm-modal.scss new file mode 100644 index 00000000..c7ff4642 --- /dev/null +++ b/src/components/grw-offline-confirm-modal/grw-offline-confirm-modal.scss @@ -0,0 +1,81 @@ +:host { + display: block; +} + +.modal-container { + z-index: 40000; + position: fixed; + display: flex; + align-items: center; + justify-content: center; + font-family: var(--font-family); + top: 0px; + left: 0px; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.6); + + .modal-content-container { + display: flex; + justify-content: center; + flex-direction: column; + width: 380px; + height: 120px; + padding: 16px; + margin: 0px 16px; + background-color: var(--color-background); + border-radius: var(--border-radius, 8px); + } + + .modal-message-container { + display: flex; + align-items: center; + justify-content: center; + + .modal-loader { + width: 16px; + height: 16px; + border: 3px solid var(--color-primary-container); + border-bottom-color: var(--color-on-primary-container); + border-radius: 50%; + display: inline-block; + box-sizing: border-box; + animation: rotation 1s linear infinite; + margin-right: 16px; + } + + @keyframes rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + } + + .modal-buttons-container, + .modal-button-container { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 16px; + .modal-button { + cursor: pointer; + user-select: none; + font-size: 14px; + font-weight: 500; + height: 32px; + box-shadow: var(--elevation-0); + border: none; + -webkit-tap-highlight-color: transparent; + line-height: 20px; + color: var(--color-primary-app); + background-color: transparent; + font-family: var(--font-family); + } + } + .modal-button-container { + justify-content: flex-end; + } +} diff --git a/src/components/grw-offline-confirm-modal/grw-offline-confirm-modal.tsx b/src/components/grw-offline-confirm-modal/grw-offline-confirm-modal.tsx new file mode 100644 index 00000000..c54a2d16 --- /dev/null +++ b/src/components/grw-offline-confirm-modal/grw-offline-confirm-modal.tsx @@ -0,0 +1,148 @@ +import { Component, Event, EventEmitter, Fragment, Host, Listen, Prop, State, h } from '@stencil/core'; +import { Mode } from 'types/types'; + +@Component({ + tag: 'grw-offline-confirm-modal', + styleUrl: 'grw-offline-confirm-modal.scss', + shadow: true, +}) +export class GrwOfflineConfirmModal { + @State() showOfflineModal = false; + @State() showConfirmModal = false; + @State() showLoaderModal = false; + @State() showSuccessModal = false; + @State() showConfirmDeleteModal = false; + @State() showDeletingMessage = false; + @State() showDeleteSuccessMessage = false; + + @Event() downloadPress: EventEmitter; + @Event() deletePress: EventEmitter; + + @Prop() mode: Mode; + + @Listen('downloadConfirm', { target: 'window' }) + onDownloadConfirm() { + this.showLoaderModal = false; + this.showSuccessModal = false; + this.showDeleteSuccessMessage = false; + this.showDeletingMessage = false; + this.showConfirmDeleteModal = false; + document.body.style.overflow = `hidden`; + this.showOfflineModal = true; + this.showConfirmModal = true; + } + + @Listen('downloadedSuccessConfirm', { target: 'window' }) + onDownloadedSuccessConfirm() { + this.showLoaderModal = false; + this.showSuccessModal = true; + } + + @Listen('deleteConfirm', { target: 'window' }) + onDeleteConfirm() { + this.showLoaderModal = false; + this.showSuccessModal = false; + this.showDeleteSuccessMessage = false; + document.body.style.overflow = `hidden`; + this.showOfflineModal = true; + this.showConfirmModal = true; + this.showConfirmDeleteModal = true; + } + + @Listen('deleteSuccessConfirm', { target: 'window' }) + onDeleteSuccessConfirm() { + this.showLoaderModal = false; + this.showSuccessModal = true; + this.showDeleteSuccessMessage = true; + } + + handleOkDeleteModal() { + this.showDeletingMessage = true; + this.showConfirmDeleteModal = false; + this.showConfirmModal = false; + this.showLoaderModal = true; + this.deletePress.emit(); + } + + handleOkDownloadModal() { + this.showConfirmModal = false; + this.showLoaderModal = true; + this.downloadPress.emit(); + } + + handleCancelModal() { + document.body.style.overflow = `visible`; + this.showOfflineModal = false; + } + + render() { + return ( + + {this.showOfflineModal && ( + + )} + + ); + } +} diff --git a/src/components/grw-offline-confirm-modal/readme.md b/src/components/grw-offline-confirm-modal/readme.md new file mode 100644 index 00000000..31f5dfaa --- /dev/null +++ b/src/components/grw-offline-confirm-modal/readme.md @@ -0,0 +1,45 @@ +# grw-offline-confirm-modal + + + + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| -------- | --------- | ----------- | ------------------------------------------------------------------ | ----------- | +| `mode` | `mode` | | `"outdoor" \| "touristicContents" \| "touristicEvents" \| "treks"` | `undefined` | + + +## Events + +| Event | Description | Type | +| --------------- | ----------- | --------------------- | +| `deletePress` | | `CustomEvent` | +| `downloadPress` | | `CustomEvent` | + + +## Shadow Parts + +| Part | Description | +| ---------------- | ----------- | +| `"modal-button"` | | + + +## Dependencies + +### Used by + + - [grw-app](../grw-app) + +### Graph +```mermaid +graph TD; + grw-app --> grw-offline-confirm-modal + style grw-offline-confirm-modal fill:#f9f,stroke:#333,stroke-width:4px +``` + +---------------------------------------------- + +*Built with [StencilJS](https://stenciljs.com/)* diff --git a/src/services/grw-db.service.ts b/src/services/grw-db.service.ts index b78071d8..51cd49a5 100644 --- a/src/services/grw-db.service.ts +++ b/src/services/grw-db.service.ts @@ -433,7 +433,6 @@ export async function writeOrUpdateFilesInStore(value, imagesRegExp, onlyFirstAr export async function writeOrUpdateTilesInStore(offlineLayer: TileLayerOffline, bounds, minZoom, MaxZoom) { const tilesToStore: TileInfo[] = []; - for (let index = minZoom; index <= MaxZoom; index++) { tilesToStore.push( ...offlineLayer.getTileUrls(L.bounds(L.CRS.EPSG3857.latLngToPoint(bounds.getNorthWest(), index), L.CRS.EPSG3857.latLngToPoint(bounds.getSouthEast(), index)), index),