{ "version": 3, "sources": ["src/app/modules/shell/aspect-ratio/aspect-ratio.component.ts", "src/app/modules/shell/aspect-ratio/aspect-ratio.component.html", "src/app/utils/transfer-state-helper.ts", "src/app/modules/shell/image-shell/image-shell.component.ts", "src/app/modules/shell/image-shell/image-shell.component.html"], "sourcesContent": ["import { Component, Input, HostBinding } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'app-aspect-ratio',\r\n templateUrl: './aspect-ratio.component.html',\r\n styleUrls: ['./aspect-ratio.component.scss'],\r\n standalone: true\r\n})\r\nexport class AspectRatioComponent {\r\n\r\n @HostBinding('style.padding') ratioPadding = '0px';\r\n\r\n @Input()\r\n set ratio(ratio: { w: number, h: number }) {\r\n ratio = (ratio !== undefined && ratio !== null) ? ratio : {w: 1, h: 1};\r\n\r\n const heightRatio = (ratio.h / ratio.w * 100) + '%';\r\n\r\n // Conserve aspect ratio (see: http://stackoverflow.com/a/10441480/1116959)\r\n this.ratioPadding = '0px 0px ' + heightRatio + ' 0px';\r\n }\r\n\r\n constructor() { }\r\n}\r\n", "
\r\n \r\n
\r\n", "import { isPlatformServer } from '@angular/common';\r\nimport { Inject, Injectable, PLATFORM_ID, makeStateKey, TransferState } from '@angular/core';\r\n\r\nimport { Observable, of } from 'rxjs';\r\nimport { tap } from 'rxjs/operators';\r\n\r\nexport enum ImageShellState {\r\n SSR = 'ssr-loaded',\r\n BROWSER_FROM_SSR = 'browser-loaded-from-ssr',\r\n NOT_FOUND = 'not-found'\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class TransferStateHelper {\r\n\r\n constructor(\r\n @Inject(PLATFORM_ID) private platformId: object,\r\n private state: TransferState,\r\n ) { }\r\n\r\n // Method with generic param\r\n checkDataSourceState(stateKey: string, dataSource: Observable): Observable {\r\n const dataKey = makeStateKey(stateKey);\r\n\r\n if (isPlatformServer(this.platformId)) {\r\n // When loading resource in the server, store the result in the TransferState\r\n // to use when transitioning to the browser from the SSR rendered app\r\n return dataSource.pipe(\r\n tap(\r\n (data: T) => {\r\n this.state.set(dataKey, data);\r\n }\r\n )\r\n );\r\n } else {\r\n // Check if we have data in the TransferState\r\n if (this.state.hasKey(dataKey)) {\r\n const stateData = this.state.get(dataKey, null);\r\n\r\n if (stateData && stateData !== null) {\r\n const cachedDataSource = of(stateData);\r\n\r\n // After using it, remove data from state\r\n // this.state.remove(dataKey);\r\n\r\n // Set a flag to track if the dataSource is being cached in the server state or not\r\n Object.assign(cachedDataSource, {ssr_state: true});\r\n\r\n return cachedDataSource;\r\n } else {\r\n return dataSource;\r\n }\r\n } else {\r\n return dataSource;\r\n }\r\n }\r\n }\r\n\r\n // This method checks if a specific image was previously handled in the server\r\n checkImageShellState(stateKey: string, imageSource: string): ImageShellState {\r\n let imageState: ImageShellState = ImageShellState.NOT_FOUND;\r\n\r\n // Make sure we are not dealing with empty image sources\r\n if (imageSource !== '') {\r\n // We will store a collection of image sources in the state\r\n const dataKey = makeStateKey>(stateKey);\r\n\r\n if (isPlatformServer(this.platformId)) {\r\n // When loading resource in the server, store the result in the TransferState\r\n // to use when transitioning to the browser from the SSR rendered app\r\n\r\n const stateImages = this.state.get(dataKey, []);\r\n stateImages.push(imageSource);\r\n\r\n this.state.set(dataKey, stateImages);\r\n\r\n // Running in the server, in this execution the image is set in the transfer state for the first time\r\n imageState = ImageShellState.SSR;\r\n } else {\r\n // Check if we have data in the TransferState\r\n if (this.state.hasKey(dataKey)) {\r\n const stateData = this.state.get(dataKey, []);\r\n\r\n // Check if the image was previously loaded in the server\r\n if (stateData.includes(imageSource)) {\r\n imageState = ImageShellState.BROWSER_FROM_SSR;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return imageState;\r\n }\r\n}\r\n", "import { Component, Input, HostBinding } from '@angular/core';\r\nimport { ImageShellState, TransferStateHelper } from 'src/app/utils/transfer-state-helper';\r\nimport { environment } from 'src/environments/environment';\r\nimport { NgIf } from '@angular/common';\r\nimport { IonicModule } from '@ionic/angular';\r\n\r\n@Component({\r\n selector: 'app-image-shell',\r\n templateUrl: './image-shell.component.html',\r\n styleUrls: ['./image-shell.component.scss'],\r\n imports: [IonicModule, NgIf],\r\n standalone: true,\r\n})\r\nexport class ImageShellComponent {\r\n // To debug shell styles, change configuration in the environment file\r\n private debugDisplay = (environment.appShellConfig && environment.appShellConfig.debug) ? environment.appShellConfig.debug : false;\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention,no-underscore-dangle,id-blacklist,id-match\r\n _src = '';\r\n // eslint-disable-next-line @typescript-eslint/naming-convention,no-underscore-dangle,id-blacklist,id-match\r\n _alt = '';\r\n // eslint-disable-next-line @typescript-eslint/naming-convention,no-underscore-dangle,id-blacklist,id-match\r\n _loadingStrategy: 'lazy' | 'eager' = 'lazy';\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match\r\n _display = '';\r\n\r\n @HostBinding('class.img-ssr') imageSSR = false;\r\n @HostBinding('class.img-loaded') imageLoaded = false;\r\n @HostBinding('class.img-error') imageError = false;\r\n\r\n @HostBinding('attr.data-error') errorMessage = 'Could not load image';\r\n\r\n @HostBinding('style.backgroundImage') backgroundImage: string;\r\n\r\n @HostBinding('attr.display')\r\n @Input()\r\n set display(val: string) {\r\n this._display = (val !== undefined && val !== null) ? val : '';\r\n\r\n // For display 'cover' we use a hidden aux image. As it's hidden, if set loading to 'lazy' it won't ever trigger the loading mechanism\r\n if (this._display === 'cover') {\r\n this._loadingStrategy = 'eager';\r\n }\r\n }\r\n get display(): string {\r\n return this._display;\r\n }\r\n\r\n @Input()\r\n set src(val: string) {\r\n if (!this.debugDisplay) {\r\n this._src = (val !== undefined && val !== null) ? val : '';\r\n }\r\n\r\n // When using SSR (Server Side Rendering), avoid the loading animation while the image resource is being loaded\r\n const imageState = this.transferStateHelper.checkImageShellState('shell-images-state', this._src);\r\n\r\n if (imageState === ImageShellState.SSR || imageState === ImageShellState.BROWSER_FROM_SSR) {\r\n this._imageProcessedInServer();\r\n } else {\r\n if (this._display === 'cover') {\r\n // Unset the background-image until the image is loaded\r\n this.backgroundImage = 'unset';\r\n }\r\n }\r\n }\r\n\r\n @Input()\r\n set alt(val: string) {\r\n this._alt = (val !== undefined && val !== null) ? val : '';\r\n }\r\n\r\n constructor(\r\n private transferStateHelper: TransferStateHelper\r\n ) { }\r\n\r\n _imageProcessedInServer(): void {\r\n this.imageSSR = true;\r\n\r\n // Also set backgroundImage so it's ready when transitioning from SSR to the browser\r\n if (this._display === 'cover') {\r\n this.backgroundImage = 'url(' + this._src + ')';\r\n }\r\n }\r\n\r\n _imageLoaded(): void {\r\n this.imageLoaded = true;\r\n\r\n // If it's a cover image then set the background-image property accordingly\r\n if (this._display === 'cover') {\r\n // Now that the image is loaded, set the background image\r\n this.backgroundImage = 'url(' + this._src + ')';\r\n }\r\n }\r\n\r\n _imageLoadError(event: Event): void {\r\n // Image error event get's called when the src is empty. We use emty values for the shell.\r\n // (see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Image_loading_errors)\r\n // Avoid that shell case\r\n if (this._src && this._src !== '') {\r\n this.imageLoaded = false;\r\n this.imageSSR = false;\r\n\r\n setTimeout(() => {\r\n this.imageError = true;\r\n }, 500);\r\n }\r\n }\r\n}\r\n", "\r\n\r\n\r\n"], "mappings": "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", "names": ["AspectRatioComponent", "ratio", "w", "h", "heightRatio", "ratioPadding", "constructor", "selectors", "hostVars", "hostBindings", "rf", "ctx", "\u0275\u0275styleProp", "\u0275\u0275elementStart", "\u0275\u0275projection", "\u0275\u0275elementEnd", "ImageShellState", "TransferStateHelper", "constructor", "platformId", "state", "checkDataSourceState", "stateKey", "dataSource", "dataKey", "isPlatformServer", "pipe", "tap", "data", "set", "hasKey", "stateData", "get", "cachedDataSource", "of", "Object", "assign", "ssr_state", "checkImageShellState", "imageSource", "imageState", "NOT_FOUND", "stateImages", "push", "SSR", "includes", "BROWSER_FROM_SSR", "\u0275\u0275inject", "PLATFORM_ID", "TransferState", "factory", "\u0275fac", "providedIn", "\u0275\u0275projection", "ImageShellComponent", "display", "val", "_display", "_loadingStrategy", "src", "debugDisplay", "_src", "imageState", "transferStateHelper", "checkImageShellState", "ImageShellState", "SSR", "BROWSER_FROM_SSR", "_imageProcessedInServer", "backgroundImage", "alt", "_alt", "constructor", "environment", "appShellConfig", "debug", "imageSSR", "imageLoaded", "imageError", "errorMessage", "_imageLoaded", "_imageLoadError", "event", "setTimeout", "\u0275\u0275directiveInject", "TransferStateHelper", "selectors", "hostVars", "hostBindings", "rf", "ctx", "\u0275\u0275styleProp", "\u0275\u0275classProp", "\u0275\u0275element", "\u0275\u0275elementStart", "\u0275\u0275listener", "$event", "\u0275\u0275elementEnd", "\u0275\u0275template", "ImageShellComponent_ng_content_2_Template", "\u0275\u0275advance", "\u0275\u0275property", "\u0275\u0275sanitizeUrl", "IonicModule", "IonSpinner", "NgIf", "styles"] }