From 102d019eb4cf6d9133c17b711cb8a0b1cbc7bdad Mon Sep 17 00:00:00 2001 From: khalifan-kfan Date: Tue, 18 Jul 2023 12:34:01 +0300 Subject: [PATCH 01/10] initial player set up --- .../activity-details.component.html | 5 +- .../activity-details.component.scss | 1 + .../activity-details.component.ts | 230 +++++- .../src/app/service/video-player.ts | 8 + .../src/assets/resources/contents.json | 18 +- package.json | 4 +- yarn.lock | 769 ++++++------------ 7 files changed, 498 insertions(+), 537 deletions(-) create mode 100644 apps/picsa-tools/manual-tool/src/app/service/video-player.ts diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html index 9c56e3ca2..dc3275977 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html @@ -1,7 +1,10 @@

{{ activity?.label }}

- + + +
+
diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss index 6daec6f91..65b53272c 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss @@ -26,6 +26,7 @@ mat-icon{ width: 3rem; } + .svg-item{ flex-direction: column; display: flex; diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts index 682377bef..aa6f0e480 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts @@ -1,22 +1,244 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, Input, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { IManualActivity, PICSA_MANUAL_GRID_DATA } from '../../data/manual-contents'; +import { setVideoPlayer } from './../../service/video-player'; @Component({ selector: 'picsa-manual-activity-details', templateUrl: './activity-details.component.html', styleUrls: ['./activity-details.component.scss'], }) - -export class ActivityDetailsComponent implements OnInit { +export class ActivityDetailsComponent implements OnInit, OnDestroy { activity?: IManualActivity; + // videoPlayer: any; + @Input() url: string; + @Input() sturl: string; + @Input() stlang: string; + @Input() stoptions: any; + @Input() rate: number; + @Input() exitOnEnd: boolean; + @Input() loopOnEnd: boolean; + @Input() pipEnabled: boolean; + @Input() bkmodeEnabled: boolean; + @Input() showControls: boolean; + @Input() displayMode: string; + @Input() testApi: boolean; + @Input() platform: string; + + private videoPlayer: any; + private handlerPlay: any; + private handlerPause: any; + private handlerEnded: any; + private handlerReady: any; + private handlerPlaying: any; + private handlerExit: any; + private first = false; + private mUrl: any = null; + // private mSturl: string = null; + // private mStlang: string = null; + private mStoptions: any = null; + private mRate = 1.0; + private mExitOnEnd = true; + private mLoopOnEnd = false; + private mPipEnabled = true; + private mBkmodeEnabled = true; + private mShowControls = true; + private mDisplayMode = 'portrait'; + private apiTimer1: any; + private apiTimer2: any; + private apiTimer3: any; + private mTestApi: boolean; constructor(private route: ActivatedRoute) {} - ngOnInit() { + async ngOnInit() { const activityId = this.route.snapshot.params.id; if (activityId) { this.activity = PICSA_MANUAL_GRID_DATA.find((activity) => activity.id === activityId); } + this.mTestApi = this.testApi ? this.testApi : false; + const player: any = await setVideoPlayer(); + this.videoPlayer = player.plugin; + await this.addListenersToPlayerPlugin(); + } + async ionViewDidEnter() { + this.mUrl = this.activity?.video; + this.mStoptions = this.stoptions; + this.mRate = this.rate; + this.mExitOnEnd = this.exitOnEnd; + this.mLoopOnEnd = this.loopOnEnd; + this.mPipEnabled = this.pipEnabled; + this.mBkmodeEnabled = this.bkmodeEnabled; + this.mShowControls = this.showControls; + this.mDisplayMode = this.displayMode; + if (this.mUrl != null && this.mUrl != undefined) { + if (this.mTestApi) { + this.first = true; + } + const res: any = await this.videoPlayer.initPlayer({ + mode: 'fullscreen', + url: this.mUrl, + subtitleOptions: this.mStoptions, + playerId: 'fullscreen', + rate: this.mRate, + exitOnEnd: this.mExitOnEnd, + loopOnEnd: this.mLoopOnEnd, + pipEnabled: this.mPipEnabled, + bkmodeEnabled: this.mBkmodeEnabled, + showControls: this.mShowControls, + displayMode: this.mDisplayMode, + componentTag: 'app-fullscreen', + }); + console.log(`res ${JSON.stringify(res)}`); + if (!res.result && (this.platform === 'ios' || this.platform === 'android')) { + console.log(res.message); + } + console.log('res.result ', res.result); + if (!res.result) { + console.log(`res.message ${res.message}`); + } + } + } + private async addListenersToPlayerPlugin(): Promise { + this.handlerPlay = await this.videoPlayer.addListener( + 'jeepCapVideoPlayerPlay', + (data: any) => this.playerPlay(data), + false + ); + this.handlerPause = await this.videoPlayer.addListener( + 'jeepCapVideoPlayerPause', + (data: any) => this.playerPause(data), + false + ); + this.handlerEnded = await this.videoPlayer.addListener( + 'jeepCapVideoPlayerEnded', + (data: any) => this.playerEnd(data), + false + ); + this.handlerExit = await this.videoPlayer.addListener( + 'jeepCapVideoPlayerExit', + (data: any) => this.playerExit(data), + false + ); + this.handlerReady = await this.videoPlayer.addListener( + 'jeepCapVideoPlayerReady', + async (data: any) => this.playerReady(data), + false + ); + return; + } + private async playerPlay(data: any): Promise { + console.log(`Event jeepCapVideoPlayerPlay ${data}`); + return; + } + private async playerPause(data: any): Promise { + console.log(`Event jeepCapVideoPlayerPause ${data}`); + return; + } + private async playerEnd(data: any): Promise { + console.log(`Event jeepCapVideoPlayerEnded ${data}`); + // await this.leaveModal(); + return; + } + private async playerExit(data: any): Promise { + console.log(`Event jeepCapVideoPlayerExit ${data}`); + // await this.leaveModal(); + return; + } + private async playerReady(data: any): Promise { + console.log(`Event jeepCapVideoPlayerReady ${data}`); + console.log(`testVideoPlayerPlugin testAPI ${this.mTestApi}`); + console.log(`testVideoPlayerPlugin first ${this.first}`); + if (this.mTestApi && this.first) { + // test the API + this.first = false; + console.log('testVideoPlayerPlugin calling isPlaying '); + let isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); + console.log(` isPlaying ${isPlaying}`); + this.apiTimer1 = setTimeout(async () => { + let pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); + console.log(`pause ${pause}`); + let retRate: any = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); + console.log(`rate ${retRate.value}`); + retRate = await this.videoPlayer.setRate({ playerId: 'fullscreen', rate: 0.5 }); + console.log(`new rate ${retRate.value}`); + isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); + console.log(`const isPlaying after pause ${isPlaying}`); + const currentTime = await this.videoPlayer.getCurrentTime({ playerId: 'fullscreen' }); + console.log('const currentTime ', currentTime); + let muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); + if (muted.value) { + console.log('getMuted true'); + } else { + console.log('getMuted false'); + } + let setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: !muted.value }); + if (setMuted.value) { + console.log('setMuted true'); + } else { + console.log('setMuted false'); + } + muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); + if (muted.value) { + console.log('getMuted true'); + } else { + console.log('getMuted false'); + } + let duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); + console.log(`duration ${duration}`); + // valid for movies havin a duration > 25 + const seektime = + currentTime.value + 0.5 * duration.value < duration.value - 25 + ? currentTime.value + 0.5 * duration.value + : duration.value - 25; + let setCurrentTime = await this.videoPlayer.setCurrentTime({ playerId: 'fullscreen', seektime }); + console.log('setCurrentTime ', setCurrentTime.value); + let play = await this.videoPlayer.play({ playerId: 'fullscreen' }); + console.log(`$$$ play ${play}`); + retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); + console.log(`$$$ rate ${retRate.value}`); + this.apiTimer2 = setTimeout(async () => { + setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: false }); + console.log('setMuted ', setMuted); + const setVolume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 0.5 }); + console.log(`setVolume ${setVolume}`); + let volume = await this.videoPlayer.getVolume({ playerId: 'fullscreen' }); + console.log(`Volume ${volume}`); + this.apiTimer3 = setTimeout(async () => { + pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); + console.log('const pause ', pause); + duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); + console.log(`duration ${duration}`); + volume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 1.0 }); + console.log(`Volume ${volume}`); + setCurrentTime = await this.videoPlayer.setCurrentTime({ + playerId: 'fullscreen', + seektime: duration.value - 3, + }); + console.log(`setCurrentTime ${setCurrentTime}`); + play = await this.videoPlayer.play({ playerId: 'fullscreen' }); + console.log(`xxx play ${play}`); + retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); + console.log(`xxx rate ${retRate.value}`); + }, 10000); + }, 8000); + }, 7000); + } + return; } + + + async ngOnDestroy() { + + const res: any = await this.videoPlayer.stopAllPlayers(); + clearTimeout(this.apiTimer3); + clearTimeout(this.apiTimer2); + clearTimeout(this.apiTimer1); + this.handlerPlay.remove(); + this.handlerPause.remove(); + this.handlerEnded.remove(); + this.handlerReady.remove(); + this.handlerPlaying.remove(); + this.handlerExit.remove(); +} } diff --git a/apps/picsa-tools/manual-tool/src/app/service/video-player.ts b/apps/picsa-tools/manual-tool/src/app/service/video-player.ts new file mode 100644 index 000000000..62d2f463e --- /dev/null +++ b/apps/picsa-tools/manual-tool/src/app/service/video-player.ts @@ -0,0 +1,8 @@ +import { Capacitor } from '@capacitor/core'; +import { CapacitorVideoPlayer } from 'capacitor-video-player'; + +export const setVideoPlayer = async (): Promise=> { + const platform = Capacitor.getPlatform(); + //console.log(CapacitorVideoPlayer) + return {plugin:CapacitorVideoPlayer, platform}; +}; diff --git a/apps/picsa-tools/resources-tool/src/assets/resources/contents.json b/apps/picsa-tools/resources-tool/src/assets/resources/contents.json index 656c9f8e6..f58074269 100644 --- a/apps/picsa-tools/resources-tool/src/assets/resources/contents.json +++ b/apps/picsa-tools/resources-tool/src/assets/resources/contents.json @@ -38,8 +38,8 @@ "covers/facebook.svg": { "relativePath": "covers/facebook.svg", "size_kb": 1.1, - "md5Checksum": "8626bc9119bd6b8bc0fa04e8a20b6e74", - "modifiedTime": "2022-09-28T20:19:52.986Z" + "md5Checksum": "a09b2f44f6b44b5b6e29aedba9f92029", + "modifiedTime": "2023-07-10T22:11:12.359Z" }, "covers/gender-equality-1.svg": { "relativePath": "covers/gender-equality-1.svg", @@ -49,9 +49,9 @@ }, "covers/gender-equality.svg": { "relativePath": "covers/gender-equality.svg", - "size_kb": 5.5, - "md5Checksum": "0b6599c4d8b3a87b787910b18a9d8851", - "modifiedTime": "2022-11-01T20:27:18.286Z" + "size_kb": 5.4, + "md5Checksum": "95af38f37c2179d4ad0c5288cbb236ed", + "modifiedTime": "2023-07-10T22:11:12.359Z" }, "covers/gras-nelk.jpg": { "relativePath": "covers/gras-nelk.jpg", @@ -98,8 +98,8 @@ "covers/spreadsheet.svg": { "relativePath": "covers/spreadsheet.svg", "size_kb": 2.8, - "md5Checksum": "a03a4bfb0a1791fda8e232a8b032715b", - "modifiedTime": "2022-09-30T09:35:53.529Z" + "md5Checksum": "0a1bc91188bbc03fda0a7cb2bc1aa6ce", + "modifiedTime": "2023-07-10T22:11:12.360Z" }, "covers/twitter.png": { "relativePath": "covers/twitter.png", @@ -110,8 +110,8 @@ "covers/weather.svg": { "relativePath": "covers/weather.svg", "size_kb": 3.1, - "md5Checksum": "db07c7d20d9520124c251c810c5817fd", - "modifiedTime": "2022-09-28T19:22:58.064Z" + "md5Checksum": "ca87f24916d258b8b8b5dd8343d4305b", + "modifiedTime": "2023-07-10T22:11:12.360Z" }, "covers/whatsapp.svg": { "relativePath": "covers/whatsapp.svg", diff --git a/package.json b/package.json index 71d70d115..66278a23d 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@awesome-cordova-plugins/file-opener": "^6.3.0", "@awesome-cordova-plugins/network": "^6.3.0", "@awesome-cordova-plugins/social-sharing": "^6.3.0", + "@capacitor-community/electron": "^4.1.2", "@capacitor-community/firebase-analytics": "^4.0.0", "@capacitor-community/firebase-crashlytics": "^2.0.0-1", "@capacitor-firebase/performance": "^1.3.0", @@ -61,6 +62,7 @@ "@supabase/supabase-js": "^2.22.0", "c3": "^0.7.20", "capacitor-blob-writer": "^1.1.3", + "capacitor-video-player": "^5.0.1", "cordova-plugin-codeplay-share-own-apk": "0.0.7", "cordova-plugin-file": "^7.0.0", "cordova-plugin-file-opener2": "^4.0.0", @@ -72,6 +74,7 @@ "enketo-core": "^6.1.3", "firebase": "^9.16.0", "glob": "^8.1.0", + "hls.js": "^1.4.9", "html2canvas": "^1.4.1", "leaflet": "^1.9.3", "leaflet-draw": "github:enketo/Leaflet.draw#ff730785db7fcccbf2485ffcf4dffe1238a7c617", @@ -153,7 +156,6 @@ "nx": "15.6.2", "postcss": "^8.4.5", "postcss-import": "~14.1.0", - "postcss-preset-env": "~7.5.0", "postcss-url": "~10.1.3", "prettier": "2.6.2", "prompts": "^2.4.2", diff --git a/yarn.lock b/yarn.lock index 09b7ffe5e..6e0953572 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3161,6 +3161,23 @@ __metadata: languageName: node linkType: hard +"@capacitor-community/electron@npm:^4.1.2": + version: 4.1.2 + resolution: "@capacitor-community/electron@npm:4.1.2" + dependencies: + "@capacitor/cli": ^3.5.1 + "@capacitor/core": ^3.5.1 + "@ionic/utils-fs": ~3.1.6 + chalk: ~4.1.2 + electron-is-dev: ~2.0.0 + events: ~3.3.0 + fs-extra: ~9.1.0 + mime-types: ~2.1.35 + ora: ~5.4.1 + checksum: 167c4ea897689a3df9355ba2613d23ee22b97a9ce60a29718e369aea48a588e02fded06b2f592cdd7b8dcffb7341323f2ce8ef86dbacde9df151a959bffd8855 + languageName: node + linkType: hard + "@capacitor-community/firebase-analytics@npm:^4.0.0": version: 4.0.0 resolution: "@capacitor-community/firebase-analytics@npm:4.0.0" @@ -3216,6 +3233,33 @@ __metadata: languageName: node linkType: hard +"@capacitor/cli@npm:^3.5.1": + version: 3.9.0 + resolution: "@capacitor/cli@npm:3.9.0" + dependencies: + "@ionic/cli-framework-output": ^2.2.1 + "@ionic/utils-fs": ^3.1.5 + "@ionic/utils-subprocess": ^2.1.6 + "@ionic/utils-terminal": ^2.3.0 + commander: ^6.0.0 + debug: ^4.2.0 + env-paths: ^2.2.0 + kleur: ^4.1.1 + native-run: ^1.5.0 + open: ^7.4.2 + plist: ^3.0.2 + prompts: ^2.3.2 + semver: ^7.3.2 + tar: ^6.1.11 + tslib: ^2.1.0 + xml2js: ^0.4.23 + bin: + cap: bin/capacitor + capacitor: bin/capacitor + checksum: 94647111a35a3d86603fb0432875272700d5406dc532ca29fc2fa469decefa6e12a60f8f161de0bea4e4f4ac36fbfc63f68ccc1c04879cad9d2a3b3a69d05068 + languageName: node + linkType: hard + "@capacitor/cli@npm:^4.1.0": version: 4.1.0 resolution: "@capacitor/cli@npm:4.1.0" @@ -3244,6 +3288,15 @@ __metadata: languageName: node linkType: hard +"@capacitor/core@npm:^3.5.1": + version: 3.9.0 + resolution: "@capacitor/core@npm:3.9.0" + dependencies: + tslib: ^2.1.0 + checksum: eec3e321f8077ec4ef3bc5dda2176388f0277598b6473ed05e6c86e0cf16e0e8e7f40ff078510577404b03a636a2ff431c090257e960b0af02556683b0b14b79 + languageName: node + linkType: hard + "@capacitor/core@npm:^4.0.0, @capacitor/core@npm:^4.6.2": version: 4.6.2 resolution: "@capacitor/core@npm:4.6.2" @@ -3700,128 +3753,6 @@ __metadata: languageName: node linkType: hard -"@csstools/postcss-color-function@npm:^1.1.0": - version: 1.1.0 - resolution: "@csstools/postcss-color-function@npm:1.1.0" - dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 1378858848067fce67b5b7d1daeb3082bddeacddc588cea0fd85e5d7a0bb5cd4f43fea9b96fced2bc1c45171f8900d1f5ebfe13f574c360164c79e055868befb - languageName: node - linkType: hard - -"@csstools/postcss-font-format-keywords@npm:^1.0.0": - version: 1.0.0 - resolution: "@csstools/postcss-font-format-keywords@npm:1.0.0" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.3 - checksum: 4f41dccc46b51568b0517420d150ca105c31a2652f028f070e7457213f4e950420385d72ee869d75f592811da3a03cb46d11935d51f29b73d9ab24c10b3140e5 - languageName: node - linkType: hard - -"@csstools/postcss-hwb-function@npm:^1.0.0": - version: 1.0.1 - resolution: "@csstools/postcss-hwb-function@npm:1.0.1" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: c57a74ac5c2ca9d209b325b8995932262b0498300eaab80cffb64278c2b3cb47b2203b3b5bb47e0b00532f985449be9f60f3496ed1c9cec57e4b07047a36f7a6 - languageName: node - linkType: hard - -"@csstools/postcss-ic-unit@npm:^1.0.0": - version: 1.0.0 - resolution: "@csstools/postcss-ic-unit@npm:1.0.0" - dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.3 - checksum: d194b13a66027558d2d0dd3be3b795167b5e751bb3a3e62928c77ef1c524f0d672a7658852f07e589abbb64e827096eac00d9b6d7ec79e21006fd4f6f0b3ce87 - languageName: node - linkType: hard - -"@csstools/postcss-is-pseudo-class@npm:^2.0.2": - version: 2.0.4 - resolution: "@csstools/postcss-is-pseudo-class@npm:2.0.4" - dependencies: - "@csstools/selector-specificity": ^1.0.0 - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.4 - checksum: 5506839b7d82105c8cd0155513adbc67b5ae5de298d529022eaa2a5b95536e615a9d02698fd85bc2f2ec9037e3be69d9c2f80c15b954257f5f1361536c1bb788 - languageName: node - linkType: hard - -"@csstools/postcss-normalize-display-values@npm:^1.0.0": - version: 1.0.0 - resolution: "@csstools/postcss-normalize-display-values@npm:1.0.0" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.3 - checksum: 5751a171f3ccd5d411bf1945e306b7a3191a82a52743b65c9f04ec4beffc0e087c32f024929fb51e46388bd197545699e279d87a53acfbc40dd5594e862b24af - languageName: node - linkType: hard - -"@csstools/postcss-oklab-function@npm:^1.1.0": - version: 1.1.0 - resolution: "@csstools/postcss-oklab-function@npm:1.1.0" - dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: d59616e6acc0466ce87626c50b519a26391ac643d135c0316a4bfca27396c922b67a57cbe6adda3864123f8b9c1b48a0427e499a357887f5c0f3a0aa00b1b71b - languageName: node - linkType: hard - -"@csstools/postcss-progressive-custom-properties@npm:^1.1.0, @csstools/postcss-progressive-custom-properties@npm:^1.3.0": - version: 1.3.0 - resolution: "@csstools/postcss-progressive-custom-properties@npm:1.3.0" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.3 - checksum: e281845fde5b8a80d06ec20147bd74e96a9351bebbec5e5c3a6fb37ea30a597ff84172601786a8a270662f58f708b4a3bf8d822d6318023def9773d2f6589962 - languageName: node - linkType: hard - -"@csstools/postcss-stepped-value-functions@npm:^1.0.0": - version: 1.0.0 - resolution: "@csstools/postcss-stepped-value-functions@npm:1.0.0" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.3 - checksum: 48e9c20a84f58555c0c26889db76d3cef90413e6b4e47c6d2f3895afd713181405ce2afcf3230447ee139e56fe19d568c665de0c7a19d0c16dc834f439b71d72 - languageName: node - linkType: hard - -"@csstools/postcss-unset-value@npm:^1.0.0": - version: 1.0.1 - resolution: "@csstools/postcss-unset-value@npm:1.0.1" - peerDependencies: - postcss: ^8.3 - checksum: 4d355a88ec9fd3fa80a44ffa16d3b95cf3c8b5e369780a15d58ad51dbefabfd7e5be7def239cf98d20f5a1e634ab589620be5d6c9964a335ab33cef36f3ca197 - languageName: node - linkType: hard - -"@csstools/selector-specificity@npm:1.0.0, @csstools/selector-specificity@npm:^1.0.0": - version: 1.0.0 - resolution: "@csstools/selector-specificity@npm:1.0.0" - peerDependencies: - postcss: ^8.3 - postcss-selector-parser: ^6.0.10 - checksum: cfdabe0df7d9d5e1e0b23c68d4f39afd33520d3196a4c9b9dc52942d14f32b594bd227a91cc7e933b3191306b447ca231b00b5f3ad3c2676958f3b364725a0a0 - languageName: node - linkType: hard - "@cypress/request@npm:^2.88.10": version: 2.88.10 resolution: "@cypress/request@npm:2.88.10" @@ -5075,6 +5006,17 @@ __metadata: languageName: node linkType: hard +"@ionic/cli-framework-output@npm:^2.2.1": + version: 2.2.6 + resolution: "@ionic/cli-framework-output@npm:2.2.6" + dependencies: + "@ionic/utils-terminal": 2.3.4 + debug: ^4.0.0 + tslib: ^2.0.1 + checksum: ac39c57130f4c03a0378b0269f32412a298c2f43fa6a87abc216952a51e2ee68464b8c3e70e82c0139d8f892f8986b855f971b7bb5768a857144dd4f9eacb699 + languageName: node + linkType: hard + "@ionic/cli-framework-output@npm:^2.2.5": version: 2.2.5 resolution: "@ionic/cli-framework-output@npm:2.2.5" @@ -5107,6 +5049,16 @@ __metadata: languageName: node linkType: hard +"@ionic/utils-array@npm:2.1.6": + version: 2.1.6 + resolution: "@ionic/utils-array@npm:2.1.6" + dependencies: + debug: ^4.0.0 + tslib: ^2.0.1 + checksum: 13d7b56906bb394a9362622c001578f0788f06ee2d8c724a51fb415cf4bdc1ccf1f92c2358935524f0089a660a4323d5f0bfa9403a0b3050ed921c039125b5e8 + languageName: node + linkType: hard + "@ionic/utils-fs@npm:3.1.6, @ionic/utils-fs@npm:^3.1.6": version: 3.1.6 resolution: "@ionic/utils-fs@npm:3.1.6" @@ -5119,6 +5071,18 @@ __metadata: languageName: node linkType: hard +"@ionic/utils-fs@npm:3.1.7, @ionic/utils-fs@npm:^3.1.5, @ionic/utils-fs@npm:~3.1.6": + version: 3.1.7 + resolution: "@ionic/utils-fs@npm:3.1.7" + dependencies: + "@types/fs-extra": ^8.0.0 + debug: ^4.0.0 + fs-extra: ^9.0.0 + tslib: ^2.0.1 + checksum: e917023a3a69dfb7ae7513357b46dcbbe9ac643b297034d2816409d38ea8f5a8cd1fccd525d11faadfa2e46804f8709b1e5ea46c84a340ea6aa8d76ea9fa8222 + languageName: node + linkType: hard + "@ionic/utils-object@npm:2.1.5": version: 2.1.5 resolution: "@ionic/utils-object@npm:2.1.5" @@ -5129,6 +5093,16 @@ __metadata: languageName: node linkType: hard +"@ionic/utils-object@npm:2.1.6": + version: 2.1.6 + resolution: "@ionic/utils-object@npm:2.1.6" + dependencies: + debug: ^4.0.0 + tslib: ^2.0.1 + checksum: c545f09ede118a801c7eb4c794d4b479c574a98023b752421c0b18e340cb0f509aa7d7e92ef9b1048361e194a0b6f80df8922cd56bae8201d2fb796b71d87e60 + languageName: node + linkType: hard + "@ionic/utils-process@npm:2.1.10": version: 2.1.10 resolution: "@ionic/utils-process@npm:2.1.10" @@ -5143,6 +5117,20 @@ __metadata: languageName: node linkType: hard +"@ionic/utils-process@npm:2.1.11": + version: 2.1.11 + resolution: "@ionic/utils-process@npm:2.1.11" + dependencies: + "@ionic/utils-object": 2.1.6 + "@ionic/utils-terminal": 2.3.4 + debug: ^4.0.0 + signal-exit: ^3.0.3 + tree-kill: ^1.2.2 + tslib: ^2.0.1 + checksum: 376994e15774778af7b951c22d20c19510fa2009b5ff1c2e1244be6a0d2b059eba5e7b6db6ddd9e3764c326ab35e4446a17e49f2e1deab66b4eccd008f66cc49 + languageName: node + linkType: hard + "@ionic/utils-stream@npm:3.1.5": version: 3.1.5 resolution: "@ionic/utils-stream@npm:3.1.5" @@ -5153,6 +5141,16 @@ __metadata: languageName: node linkType: hard +"@ionic/utils-stream@npm:3.1.6": + version: 3.1.6 + resolution: "@ionic/utils-stream@npm:3.1.6" + dependencies: + debug: ^4.0.0 + tslib: ^2.0.1 + checksum: cd207a12fdcfa39c3f215620dee17491aca6bf0fa39cd9c7a9a21188013113aa3f3f9e50e2eae590f2dae9f5411e54a6f9cd3916cd87837be9206ea3fedd65f3 + languageName: node + linkType: hard + "@ionic/utils-subprocess@npm:^2.1.11": version: 2.1.11 resolution: "@ionic/utils-subprocess@npm:2.1.11" @@ -5169,6 +5167,22 @@ __metadata: languageName: node linkType: hard +"@ionic/utils-subprocess@npm:^2.1.6": + version: 2.1.12 + resolution: "@ionic/utils-subprocess@npm:2.1.12" + dependencies: + "@ionic/utils-array": 2.1.6 + "@ionic/utils-fs": 3.1.7 + "@ionic/utils-process": 2.1.11 + "@ionic/utils-stream": 3.1.6 + "@ionic/utils-terminal": 2.3.4 + cross-spawn: ^7.0.3 + debug: ^4.0.0 + tslib: ^2.0.1 + checksum: 2821e535d747e5b84addc0e4737211216190cb9e5563ee973b1eeed329f8114026ac238322ff37fecb13b5e5dc2556de3a7b11aaf265b95f572075e00695e6f6 + languageName: node + linkType: hard + "@ionic/utils-terminal@npm:2.3.3, @ionic/utils-terminal@npm:^2.3.3": version: 2.3.3 resolution: "@ionic/utils-terminal@npm:2.3.3" @@ -5186,6 +5200,23 @@ __metadata: languageName: node linkType: hard +"@ionic/utils-terminal@npm:2.3.4, @ionic/utils-terminal@npm:^2.3.0": + version: 2.3.4 + resolution: "@ionic/utils-terminal@npm:2.3.4" + dependencies: + "@types/slice-ansi": ^4.0.0 + debug: ^4.0.0 + signal-exit: ^3.0.3 + slice-ansi: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + tslib: ^2.0.1 + untildify: ^4.0.0 + wrap-ansi: ^7.0.0 + checksum: d32fbeb6c7b355717a28ea2b0741c50c2fee5f959c25373f17887f6d8150523bffc54caaa1cd8c585809f94bdcbfd7f13ade63d02a9f122e93ff7d4ca1645698 + languageName: node + linkType: hard + "@istanbuljs/load-nyc-config@npm:^1.0.0": version: 1.1.0 resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" @@ -8629,6 +8660,13 @@ __metadata: languageName: node linkType: hard +"@xmldom/xmldom@npm:^0.8.8": + version: 0.8.9 + resolution: "@xmldom/xmldom@npm:0.8.9" + checksum: b324f35170bf1ad43afa9e8c85372149e626d6f54ffc3ea3d34591eb6d945202470f631a53107f634e4258afb0c0067ee243f210ce9b6050189c677c3d481c7c + languageName: node + linkType: hard + "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -9218,7 +9256,7 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:^10.4.0, autoprefixer@npm:^10.4.6": +"autoprefixer@npm:^10.4.0": version: 10.4.7 resolution: "autoprefixer@npm:10.4.7" dependencies: @@ -10008,6 +10046,16 @@ __metadata: languageName: node linkType: hard +"capacitor-video-player@npm:^5.0.1": + version: 5.0.1 + resolution: "capacitor-video-player@npm:5.0.1" + peerDependencies: + "@capacitor/core": ^5.0.0 + hls.js: ^1.4.0 + checksum: d316c4062bc0ad5b2c5104b127871c2f33bfadc4826e604856e635769fba15b417b90f8e062ee924544ae61cf588846115a0ceb4503f91a1fa34295c0db8afe1 + languageName: node + linkType: hard + "caseless@npm:~0.12.0": version: 0.12.0 resolution: "caseless@npm:0.12.0" @@ -10043,7 +10091,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": +"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2, chalk@npm:~4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -10402,6 +10450,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^6.0.0": + version: 6.2.1 + resolution: "commander@npm:6.2.1" + checksum: d7090410c0de6bc5c67d3ca41c41760d6d268f3c799e530aafb73b7437d1826bbf0d2a3edac33f8b57cc9887b4a986dce307fa5557e109be40eadb7c43b21742 + languageName: node + linkType: hard + "commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" @@ -10923,19 +10978,6 @@ __metadata: languageName: node linkType: hard -"css-blank-pseudo@npm:^3.0.3": - version: 3.0.3 - resolution: "css-blank-pseudo@npm:3.0.3" - dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - bin: - css-blank-pseudo: dist/cli.cjs - checksum: 9be0a13885a99d8ba9e1f45ea66e801d4da75b58c1c3c516a40772fa3a93ef9952b15dcac0418acbb6c89daaae0572819647701b8e553a02972826e33d4cd67f - languageName: node - linkType: hard - "css-declaration-sorter@npm:^6.2.2": version: 6.3.0 resolution: "css-declaration-sorter@npm:6.3.0" @@ -10945,19 +10987,6 @@ __metadata: languageName: node linkType: hard -"css-has-pseudo@npm:^3.0.4": - version: 3.0.4 - resolution: "css-has-pseudo@npm:3.0.4" - dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - bin: - css-has-pseudo: dist/cli.cjs - checksum: 8f165d68f6621891d9fa1d874794916a52ed8847dfbec591523ad68774650cc1eae062ba08f59514666e04aeba27be72c9b211892f3a187c5ba6e287bd4260e7 - languageName: node - linkType: hard - "css-line-break@npm:^2.1.0": version: 2.1.0 resolution: "css-line-break@npm:2.1.0" @@ -11028,17 +11057,6 @@ __metadata: languageName: node linkType: hard -"css-prefers-color-scheme@npm:^6.0.3": - version: 6.0.3 - resolution: "css-prefers-color-scheme@npm:6.0.3" - peerDependencies: - postcss: ^8.4 - bin: - css-prefers-color-scheme: dist/cli.cjs - checksum: 3a2b02f0454adda68861cdcaf6a0d11f462eadf165301cba61c5ec7c5f229ac261c5baa54c377d9b811ec5f21b30d72a02bc032cdad2415b3a566f08a0c47b3a - languageName: node - linkType: hard - "css-select@npm:^4.1.3, css-select@npm:^4.2.0": version: 4.3.0 resolution: "css-select@npm:4.3.0" @@ -11080,13 +11098,6 @@ __metadata: languageName: node linkType: hard -"cssdb@npm:^6.6.1": - version: 6.6.2 - resolution: "cssdb@npm:6.6.2" - checksum: 4e8d4f5ce27b3aa1a954149d418791ca01f6ce50ac5fefe0edd1594d1bf13dc2b07280b4b4cc00df73e97068e964e9f5644891bdeabc5fb5b1e4186466a29b0d - languageName: node - linkType: hard - "cssesc@npm:^3.0.0": version: 3.0.0 resolution: "cssesc@npm:3.0.0" @@ -11639,7 +11650,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:~4.3.1, debug@npm:~4.3.2": +"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.2.0, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:~4.3.1, debug@npm:~4.3.2": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -12134,6 +12145,13 @@ __metadata: languageName: node linkType: hard +"electron-is-dev@npm:~2.0.0": + version: 2.0.0 + resolution: "electron-is-dev@npm:2.0.0" + checksum: 7393f46f06153d70a427ea904c60a092e50fbf1015c26c342cebb8324ada8c9e0c0f1f02867af56d9cc76f47be17da8cb311ea6bdc83343e7ebd2323ec4014c8 + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.4.118": version: 1.4.144 resolution: "electron-to-chromium@npm:1.4.144" @@ -13058,7 +13076,7 @@ __metadata: languageName: node linkType: hard -"events@npm:^3.2.0": +"events@npm:^3.2.0, events@npm:~3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780 @@ -13710,7 +13728,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^9.0.0, fs-extra@npm:^9.1.0": +"fs-extra@npm:^9.0.0, fs-extra@npm:^9.1.0, fs-extra@npm:~9.1.0": version: 9.1.0 resolution: "fs-extra@npm:9.1.0" dependencies: @@ -14253,6 +14271,13 @@ __metadata: languageName: node linkType: hard +"hls.js@npm:^1.4.9": + version: 1.4.9 + resolution: "hls.js@npm:1.4.9" + checksum: 51e469eb99e7093a1b71a7531731d9da8609104730f1030797d25c4e25d9d7d8a6d22603921cb9a9ee6ab26b28c569e91c68a37be92dc1f34bc58e0c5af65b99 + languageName: node + linkType: hard + "hosted-git-info@npm:^6.0.0": version: 6.1.1 resolution: "hosted-git-info@npm:6.1.1" @@ -15155,7 +15180,7 @@ __metadata: languageName: node linkType: hard -"is-wsl@npm:^2.2.0": +"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -16182,7 +16207,7 @@ __metadata: languageName: node linkType: hard -"kleur@npm:^4.1.4": +"kleur@npm:^4.1.1, kleur@npm:^4.1.4": version: 4.1.5 resolution: "kleur@npm:4.1.5" checksum: 1dc476e32741acf0b1b5b0627ffd0d722e342c1b0da14de3e8ae97821327ca08f9fb944542fb3c126d90ac5f27f9d804edbe7c585bf7d12ef495d115e0f22c12 @@ -16206,7 +16231,7 @@ __metadata: "leaflet-draw@github:enketo/Leaflet.draw#ff73078, leaflet-draw@github:enketo/Leaflet.draw#ff730785db7fcccbf2485ffcf4dffe1238a7c617": version: 1.0.4 resolution: "leaflet-draw@https://github.com/enketo/Leaflet.draw.git#commit=ff730785db7fcccbf2485ffcf4dffe1238a7c617" - checksum: b08b88994769667f11f2b6a8937656c89cea34dafd4661abab0b48b4b97f3bddbdce7b23ddfdb8d7c6335e065530e32a70e281314afa34afa134bf68597945fc + checksum: 253998170af27f886d05b245c85429767e272647221daaf8d94ff5b86f75b8cbb96cc76a8a88492243166a214bc3b66b3ae704a81f74c862f09ac6c9495f731e languageName: node linkType: hard @@ -16968,7 +16993,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34, mime-types@npm:~2.1.35": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -17333,6 +17358,27 @@ __metadata: languageName: node linkType: hard +"native-run@npm:^1.5.0": + version: 1.7.2 + resolution: "native-run@npm:1.7.2" + dependencies: + "@ionic/utils-fs": ^3.1.6 + "@ionic/utils-terminal": ^2.3.3 + bplist-parser: ^0.3.2 + debug: ^4.3.4 + elementtree: ^0.1.7 + ini: ^3.0.1 + plist: ^3.0.6 + split2: ^4.1.0 + through2: ^4.0.2 + tslib: ^2.4.0 + yauzl: ^2.10.0 + bin: + native-run: bin/native-run + checksum: e892344602772fba4eb5fed29e18305ed7106c02e8b9ce166e20e98a352fbc7b335d9ef101c52448c11b5888e560da9008c3e841f1915810631b1f40a6666693 + languageName: node + linkType: hard + "native-run@npm:^1.6.0": version: 1.7.0 resolution: "native-run@npm:1.7.0" @@ -18079,6 +18125,16 @@ __metadata: languageName: node linkType: hard +"open@npm:^7.4.2": + version: 7.4.2 + resolution: "open@npm:7.4.2" + dependencies: + is-docker: ^2.0.0 + is-wsl: ^2.1.1 + checksum: 3333900ec0e420d64c23b831bc3467e57031461d843c801f569b2204a1acc3cd7b3ec3c7897afc9dde86491dfa289708eb92bba164093d8bd88fb2c231843c91 + languageName: node + linkType: hard + "opener@npm:^1.5.1": version: 1.5.2 resolution: "opener@npm:1.5.2" @@ -18125,7 +18181,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:5.4.1, ora@npm:^5.1.0, ora@npm:^5.4.1": +"ora@npm:5.4.1, ora@npm:^5.1.0, ora@npm:^5.4.1, ora@npm:~5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" dependencies: @@ -18522,6 +18578,7 @@ __metadata: "@awesome-cordova-plugins/network": ^6.3.0 "@awesome-cordova-plugins/social-sharing": ^6.3.0 "@biesbjerg/ngx-translate-extract-marker": ^1.0.0 + "@capacitor-community/electron": ^4.1.2 "@capacitor-community/firebase-analytics": ^4.0.0 "@capacitor-community/firebase-crashlytics": ^2.0.0-1 "@capacitor-firebase/performance": ^1.3.0 @@ -18566,6 +18623,7 @@ __metadata: autoprefixer: ^10.4.0 c3: ^0.7.20 capacitor-blob-writer: ^1.1.3 + capacitor-video-player: ^5.0.1 cordova-plugin-codeplay-share-own-apk: 0.0.7 cordova-plugin-file: ^7.0.0 cordova-plugin-file-opener2: ^4.0.0 @@ -18587,6 +18645,7 @@ __metadata: firebase: ^9.16.0 fs-extra: ^10.1.0 glob: ^8.1.0 + hls.js: ^1.4.9 html2canvas: ^1.4.1 husky: ^8.0.0 jest: 28.1.1 @@ -18610,7 +18669,6 @@ __metadata: parse: 3.4.2 postcss: ^8.4.5 postcss-import: ~14.1.0 - postcss-preset-env: ~7.5.0 postcss-url: ~10.1.3 pouchdb: ^8.0.1 pouchdb-adapter-http: ^8.0.1 @@ -18689,6 +18747,17 @@ __metadata: languageName: node linkType: hard +"plist@npm:^3.0.2": + version: 3.1.0 + resolution: "plist@npm:3.1.0" + dependencies: + "@xmldom/xmldom": ^0.8.8 + base64-js: ^1.5.1 + xmlbuilder: ^15.1.1 + checksum: c8ea013da8646d4c50dff82f9be39488054621cc229957621bb00add42b5d4ce3657cf58d4b10c50f7dea1a81118f825838f838baeb4e6f17fab453ecf91d424 + languageName: node + linkType: hard + "plist@npm:^3.0.5, plist@npm:^3.0.6": version: 3.0.6 resolution: "plist@npm:3.0.6" @@ -18717,17 +18786,6 @@ __metadata: languageName: node linkType: hard -"postcss-attribute-case-insensitive@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-attribute-case-insensitive@npm:5.0.0" - dependencies: - postcss-selector-parser: ^6.0.2 - peerDependencies: - postcss: ^8.0.2 - checksum: 6e0e872af10ba040af79fd0ee63b29cd6bc87a23a146fe71f9942d15769619c1f5b993b3238bdf30eb4f4c24887d2b85755692bc17e21e0ed3b24bd650cbf38b - languageName: node - linkType: hard - "postcss-calc@npm:^8.2.3": version: 8.2.4 resolution: "postcss-calc@npm:8.2.4" @@ -18740,50 +18798,6 @@ __metadata: languageName: node linkType: hard -"postcss-clamp@npm:^4.1.0": - version: 4.1.0 - resolution: "postcss-clamp@npm:4.1.0" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4.6 - checksum: 118eec936b3b035dc8d75c89973408f15c5a3de3d1ee210a2b3511e3e431d9c56e6f354b509a90540241e2225ffe3caaa2fdf25919c63348ce4583a28ada642c - languageName: node - linkType: hard - -"postcss-color-functional-notation@npm:^4.2.2": - version: 4.2.3 - resolution: "postcss-color-functional-notation@npm:4.2.3" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 1be72dd64b99a33dd8827aec0373067568721cc06d1e059d72d9680280d06546fe67bc30ed508c89c7878a9bf8ac455ec8f12af9335dcfee45a4be872476abf1 - languageName: node - linkType: hard - -"postcss-color-hex-alpha@npm:^8.0.3": - version: 8.0.3 - resolution: "postcss-color-hex-alpha@npm:8.0.3" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 3b5c1d12f86fc2b4b5b618e3842d03754eeae8c25cf252201a9bf67d2ef2845b50c23bd2854e631d8133418c13700be93a2a8689cccdfee446f25436adff9e46 - languageName: node - linkType: hard - -"postcss-color-rebeccapurple@npm:^7.0.2": - version: 7.0.2 - resolution: "postcss-color-rebeccapurple@npm:7.0.2" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.3 - checksum: 7d734ac50769f2cf42ac1e58247e45dffa3cc5fb663e67fa5b8ca1a71e1e950603263aad2e98d1629db6058b173ade0c5b5de0390d51d240da8c8674c036c8c7 - languageName: node - linkType: hard - "postcss-colormin@npm:^5.3.0": version: 5.3.0 resolution: "postcss-colormin@npm:5.3.0" @@ -18810,48 +18824,6 @@ __metadata: languageName: node linkType: hard -"postcss-custom-media@npm:^8.0.0": - version: 8.0.0 - resolution: "postcss-custom-media@npm:8.0.0" - peerDependencies: - postcss: ^8.1.0 - checksum: 11c22e1b8cd5ec13093cb563a3a44817b38127e7f97bde954027f377a6848976092fb5482b96ef0f8b3f716038d9804a01a928eebe98c2d8a1fa9806ff4d3436 - languageName: node - linkType: hard - -"postcss-custom-properties@npm:^12.1.7": - version: 12.1.7 - resolution: "postcss-custom-properties@npm:12.1.7" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 98c313c2318679b727080297a12fb6674e5ea5a3343f693167e985793afd9c7d71ce25a17139864ccfe76d32d7474bb89a2ad02830c8e40fa57ccb0a699b528d - languageName: node - linkType: hard - -"postcss-custom-selectors@npm:^6.0.0": - version: 6.0.0 - resolution: "postcss-custom-selectors@npm:6.0.0" - dependencies: - postcss-selector-parser: ^6.0.4 - peerDependencies: - postcss: ^8.1.2 - checksum: 64640f6beab468222fefc7194b5de1520b0962654d860b71996ab8582e22e9918775582488fe8567faf9d0fb6a032fbafe89a836cfe9008d0985fe4f1d2f033e - languageName: node - linkType: hard - -"postcss-dir-pseudo-class@npm:^6.0.4": - version: 6.0.4 - resolution: "postcss-dir-pseudo-class@npm:6.0.4" - dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - checksum: e493e6ed54c50b8b1bda1a0cde55fc2dec04d22983e5af178090ff592854a29866c1c255637cb047b2b40c18e6ef15c1aa45aa354735f79a7709e9add5ea2e3e - languageName: node - linkType: hard - "postcss-discard-comments@npm:^5.1.2": version: 5.1.2 resolution: "postcss-discard-comments@npm:5.1.2" @@ -18888,80 +18860,6 @@ __metadata: languageName: node linkType: hard -"postcss-double-position-gradients@npm:^3.1.1": - version: 3.1.1 - resolution: "postcss-double-position-gradients@npm:3.1.1" - dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: c59131b2d03022fbb69336766786e8cc33f6e78c8040e17d2ba499fce789c675c5dcdc4fd3abe1e76e0ecd3dc910ad8c56d49a307c0115047d21a59544afc527 - languageName: node - linkType: hard - -"postcss-env-function@npm:^4.0.6": - version: 4.0.6 - resolution: "postcss-env-function@npm:4.0.6" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 645b2363cfa21be9dcce7fe4a0f172f0af70c00d6a4c1eb3d7ff7e9cfe26d569e291ec2533114d77b12d610023cd168a92d62c38f2fc969fa333b5ae2bff5ffe - languageName: node - linkType: hard - -"postcss-focus-visible@npm:^6.0.4": - version: 6.0.4 - resolution: "postcss-focus-visible@npm:6.0.4" - dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - checksum: acd010b9ddef9b86ffb5fa604c13515ba83e18bc5118dad0a1281150f412aa0ece056c2c5ac56b55e2599f53ab0f740f5ebfdc51e1f5cfe43b8130bac0096fcc - languageName: node - linkType: hard - -"postcss-focus-within@npm:^5.0.4": - version: 5.0.4 - resolution: "postcss-focus-within@npm:5.0.4" - dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - checksum: f23d8ab757345a6deaa807d76e10c88caf4b771c38b60e1593b24aee161c503b5823620e89302226a6ae5e7afdb6ac31809241291912e4176eb594a7ddcc9521 - languageName: node - linkType: hard - -"postcss-font-variant@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-font-variant@npm:5.0.0" - peerDependencies: - postcss: ^8.1.0 - checksum: a19286589261c2bc3e20470486e1ee3b4daf34271c5020167f30856c9b30c26f23264307cb97a184d503814e1b8c5d8a1f9f64a14fd4fd9551c173dca9424695 - languageName: node - linkType: hard - -"postcss-gap-properties@npm:^3.0.3": - version: 3.0.3 - resolution: "postcss-gap-properties@npm:3.0.3" - peerDependencies: - postcss: ^8.4 - checksum: 8b7bb4292093fa66fa874143b69297d25ab83e5b8aef643f0a39cff900d9754cae55f0fb267f9230dbccbf31d538f2e885c59274daabe57a7b56716292dd89d5 - languageName: node - linkType: hard - -"postcss-image-set-function@npm:^4.0.6": - version: 4.0.6 - resolution: "postcss-image-set-function@npm:4.0.6" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: bdcd11d5ef9e5beb8ce14888125e8b526b7e01902dcb78b47ea4418297f64cf188343194670a5beb8ee5831cc902a591a8887e3512403a6b932cff921be85de3 - languageName: node - linkType: hard - "postcss-import@npm:^14.1.0, postcss-import@npm:~14.1.0": version: 14.1.0 resolution: "postcss-import@npm:14.1.0" @@ -18975,15 +18873,6 @@ __metadata: languageName: node linkType: hard -"postcss-initial@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-initial@npm:4.0.1" - peerDependencies: - postcss: ^8.0.0 - checksum: 6956953853865de79c39d11533a2860e9f38b770bb284d0010d98a00b9469e22de344e4e5fd8208614d797030487e8918dd2f2c37d9e24d4dd59d565d4fc3e12 - languageName: node - linkType: hard - "postcss-js@npm:^4.0.0": version: 4.0.0 resolution: "postcss-js@npm:4.0.0" @@ -18995,18 +18884,6 @@ __metadata: languageName: node linkType: hard -"postcss-lab-function@npm:^4.2.0": - version: 4.2.0 - resolution: "postcss-lab-function@npm:4.2.0" - dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 89ca828b8ed16feb201be7b050254560786c76392ce0a4262732438521ce13d083d1e542addf9d14da75249c58802d721df3152316bb591c9f627c7038166c2a - languageName: node - linkType: hard - "postcss-load-config@npm:^3.1.4": version: 3.1.4 resolution: "postcss-load-config@npm:3.1.4" @@ -19053,24 +18930,6 @@ __metadata: languageName: node linkType: hard -"postcss-logical@npm:^5.0.4": - version: 5.0.4 - resolution: "postcss-logical@npm:5.0.4" - peerDependencies: - postcss: ^8.4 - checksum: 17c71291ed6a03883a5aa54b9923b874c32710707d041a0f0752e6febdb09dee5d2abf4ef271978d932e4a4c948f349bb23edf633c03e3427ba15e71bfc66ac7 - languageName: node - linkType: hard - -"postcss-media-minmax@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-media-minmax@npm:5.0.0" - peerDependencies: - postcss: ^8.1.0 - checksum: 2cd7283e07a1ac1acdcc3ecbaa0e9932f8d1e7647e7aeb14d91845fcb890d60d7257ec70c825cae8d48ae80a08cc77ebc4021a0dfa32360e0cd991e2bc021607 - languageName: node - linkType: hard - "postcss-merge-longhand@npm:^5.1.5": version: 5.1.5 resolution: "postcss-merge-longhand@npm:5.1.5" @@ -19200,18 +19059,6 @@ __metadata: languageName: node linkType: hard -"postcss-nesting@npm:^10.1.4": - version: 10.1.7 - resolution: "postcss-nesting@npm:10.1.7" - dependencies: - "@csstools/selector-specificity": 1.0.0 - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.4 - checksum: 610bf1f32ea235ea825b943dbe50cf0fcf5077a63272bee45e66761ffe4f665cf460f3b7ba171fb758a5082aa2893bc7c834d5cb9e6eb6759bb2c65f0141daa1 - languageName: node - linkType: hard - "postcss-normalize-charset@npm:^5.1.0": version: 5.1.0 resolution: "postcss-normalize-charset@npm:5.1.0" @@ -19311,13 +19158,6 @@ __metadata: languageName: node linkType: hard -"postcss-opacity-percentage@npm:^1.1.2": - version: 1.1.2 - resolution: "postcss-opacity-percentage@npm:1.1.2" - checksum: b582f6d4efb6a14aa09ba49869774c2f060558a68af8a0c3aa9efc0e01b35a4985e783640806a76d4e26d2ba97556f9b5e88dde91d1664a2e2c24688e4bbcf61 - languageName: node - linkType: hard - "postcss-ordered-values@npm:^5.1.2": version: 5.1.2 resolution: "postcss-ordered-values@npm:5.1.2" @@ -19330,101 +19170,6 @@ __metadata: languageName: node linkType: hard -"postcss-overflow-shorthand@npm:^3.0.3": - version: 3.0.3 - resolution: "postcss-overflow-shorthand@npm:3.0.3" - peerDependencies: - postcss: ^8.4 - checksum: 52080efd1cefbc01a0f931f247c69470a565684cd8e3585c3f5bfa45e849abe12cd4997b031179ea66fc1339eaf72dc9e3d87a218822fd6b958ce71632da23cb - languageName: node - linkType: hard - -"postcss-page-break@npm:^3.0.4": - version: 3.0.4 - resolution: "postcss-page-break@npm:3.0.4" - peerDependencies: - postcss: ^8 - checksum: a7d08c945fc691f62c77ac701e64722218b14ec5c8fc1972b8af9c21553492d40808cf95e61b9697b1dacaf7e6180636876d7fee314f079e6c9e39ac1b1edc6f - languageName: node - linkType: hard - -"postcss-place@npm:^7.0.4": - version: 7.0.4 - resolution: "postcss-place@npm:7.0.4" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: dd1738ec9bf324889e4c51f390b4e2774c3b7a040ff277ce88c6e2f139374cf2a5d921d78b156347d57ee618e9029c1907790a50290f48918afb67c5e53bc36e - languageName: node - linkType: hard - -"postcss-preset-env@npm:~7.5.0": - version: 7.5.0 - resolution: "postcss-preset-env@npm:7.5.0" - dependencies: - "@csstools/postcss-color-function": ^1.1.0 - "@csstools/postcss-font-format-keywords": ^1.0.0 - "@csstools/postcss-hwb-function": ^1.0.0 - "@csstools/postcss-ic-unit": ^1.0.0 - "@csstools/postcss-is-pseudo-class": ^2.0.2 - "@csstools/postcss-normalize-display-values": ^1.0.0 - "@csstools/postcss-oklab-function": ^1.1.0 - "@csstools/postcss-progressive-custom-properties": ^1.3.0 - "@csstools/postcss-stepped-value-functions": ^1.0.0 - "@csstools/postcss-unset-value": ^1.0.0 - autoprefixer: ^10.4.6 - browserslist: ^4.20.3 - css-blank-pseudo: ^3.0.3 - css-has-pseudo: ^3.0.4 - css-prefers-color-scheme: ^6.0.3 - cssdb: ^6.6.1 - postcss-attribute-case-insensitive: ^5.0.0 - postcss-clamp: ^4.1.0 - postcss-color-functional-notation: ^4.2.2 - postcss-color-hex-alpha: ^8.0.3 - postcss-color-rebeccapurple: ^7.0.2 - postcss-custom-media: ^8.0.0 - postcss-custom-properties: ^12.1.7 - postcss-custom-selectors: ^6.0.0 - postcss-dir-pseudo-class: ^6.0.4 - postcss-double-position-gradients: ^3.1.1 - postcss-env-function: ^4.0.6 - postcss-focus-visible: ^6.0.4 - postcss-focus-within: ^5.0.4 - postcss-font-variant: ^5.0.0 - postcss-gap-properties: ^3.0.3 - postcss-image-set-function: ^4.0.6 - postcss-initial: ^4.0.1 - postcss-lab-function: ^4.2.0 - postcss-logical: ^5.0.4 - postcss-media-minmax: ^5.0.0 - postcss-nesting: ^10.1.4 - postcss-opacity-percentage: ^1.1.2 - postcss-overflow-shorthand: ^3.0.3 - postcss-page-break: ^3.0.4 - postcss-place: ^7.0.4 - postcss-pseudo-class-any-link: ^7.1.2 - postcss-replace-overflow-wrap: ^4.0.0 - postcss-selector-not: ^5.0.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 8fb9065e9e09a6553eeb7cc9df52d51bab942c5bfadd3b662ce8b5ae90b9aae15526397c36b7d3552d674e9b4fa5ded8612880b64aaae25c1cc5e0b22874b956 - languageName: node - linkType: hard - -"postcss-pseudo-class-any-link@npm:^7.1.2": - version: 7.1.4 - resolution: "postcss-pseudo-class-any-link@npm:7.1.4" - dependencies: - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.4 - checksum: 86e10d56daf57837ccde1d6275425522cafecbae96bd955ef200befc7fd143eedc3b00907e53e8f5207c6290b277600a8ff3f72ec037113867d6031c5d31e7f2 - languageName: node - linkType: hard - "postcss-reduce-initial@npm:^5.1.0": version: 5.1.0 resolution: "postcss-reduce-initial@npm:5.1.0" @@ -19448,26 +19193,6 @@ __metadata: languageName: node linkType: hard -"postcss-replace-overflow-wrap@npm:^4.0.0": - version: 4.0.0 - resolution: "postcss-replace-overflow-wrap@npm:4.0.0" - peerDependencies: - postcss: ^8.0.3 - checksum: 3ffe20b300a4c377a11c588b142740d8557e03c707474c45234c934190ac374750ddc92c7906c373471d273a20504a429c2062c21fdcaff830fb28e0a81ac1dc - languageName: node - linkType: hard - -"postcss-selector-not@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-selector-not@npm:5.0.0" - dependencies: - balanced-match: ^1.0.0 - peerDependencies: - postcss: ^8.1.0 - checksum: eb7bdfdd665b2f0db660d4a2061f103b96d7c326a4b9d6241d55bf32bdcd1f5defaa4c8251123c73e1bcc75dad5a2ce77c520e42ce26ecd1e42f2f842baa155f - languageName: node - linkType: hard - "postcss-selector-parser@npm:^6.0.10, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.6, postcss-selector-parser@npm:^6.0.9": version: 6.0.10 resolution: "postcss-selector-parser@npm:6.0.10" @@ -19819,7 +19544,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:^2.0.1, prompts@npm:^2.4.2": +"prompts@npm:^2.0.1, prompts@npm:^2.3.2, prompts@npm:^2.4.2": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: From 014db58b72cf63032b749bf83c6c91b9fe0a86d2 Mon Sep 17 00:00:00 2001 From: khalifan-kfan Date: Mon, 24 Jul 2023 13:38:04 +0300 Subject: [PATCH 02/10] fix video player for embedded use on web --- .../activity-details.component.html | 2 +- .../activity-details.component.scss | 3 + .../activity-details.component.ts | 313 +++++++++--------- .../app/{service => utils}/video-player.ts | 0 4 files changed, 162 insertions(+), 156 deletions(-) rename apps/picsa-tools/manual-tool/src/app/{service => utils}/video-player.ts (100%) diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html index dc3275977..64c9cf1de 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html @@ -3,7 +3,7 @@

{{ activity?.label }}

-
+
diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss index 65b53272c..710f66645 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss @@ -12,6 +12,9 @@ h2{ .video-player{ width: 70%; margin-bottom: 2rem; + display: flex; + align-items: center; + justify-content: center; } .svg-row{ display: flex; diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts index aa6f0e480..89611dfd7 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts @@ -1,8 +1,8 @@ -import { Component, Input, OnInit, OnDestroy } from '@angular/core'; +import { Component, Input, OnDestroy,OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { IManualActivity, PICSA_MANUAL_GRID_DATA } from '../../data/manual-contents'; -import { setVideoPlayer } from './../../service/video-player'; +import { setVideoPlayer } from '../../utils/video-player'; @Component({ selector: 'picsa-manual-activity-details', @@ -11,7 +11,6 @@ import { setVideoPlayer } from './../../service/video-player'; }) export class ActivityDetailsComponent implements OnInit, OnDestroy { activity?: IManualActivity; - // videoPlayer: any; @Input() url: string; @Input() sturl: string; @Input() stlang: string; @@ -27,16 +26,26 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { @Input() platform: string; private videoPlayer: any; - private handlerPlay: any; - private handlerPause: any; - private handlerEnded: any; - private handlerReady: any; - private handlerPlaying: any; - private handlerExit: any; + + //most of the code commented out is concerned with listeners + // Todo: determine if it will be required or not + + // private handlerPlay: any; + // private handlerPause: any; + // private handlerEnded: any; + // private handlerReady: any; + // private handlerPlaying: any; + // private handlerExit: any; private first = false; - private mUrl: any = null; + // private mSturl: string = null; // private mStlang: string = null; + + // private apiTimer1: any; + // private apiTimer2: any; + // private apiTimer3: any; + + private mUrl: any = null; private mStoptions: any = null; private mRate = 1.0; private mExitOnEnd = true; @@ -45,9 +54,6 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { private mBkmodeEnabled = true; private mShowControls = true; private mDisplayMode = 'portrait'; - private apiTimer1: any; - private apiTimer2: any; - private apiTimer3: any; private mTestApi: boolean; constructor(private route: ActivatedRoute) {} @@ -58,10 +64,14 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { } this.mTestApi = this.testApi ? this.testApi : false; const player: any = await setVideoPlayer(); + this.videoPlayer = player.plugin; - await this.addListenersToPlayerPlugin(); + + await this.intiateVideoPlayer() + + //await this.addListenersToPlayerPlugin(); } - async ionViewDidEnter() { + async intiateVideoPlayer() { this.mUrl = this.activity?.video; this.mStoptions = this.stoptions; this.mRate = this.rate; @@ -76,10 +86,10 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { this.first = true; } const res: any = await this.videoPlayer.initPlayer({ - mode: 'fullscreen', + mode: 'embedded',// or fullscreen (2 modes) url: this.mUrl, subtitleOptions: this.mStoptions, - playerId: 'fullscreen', + playerId: 'video-player', rate: this.mRate, exitOnEnd: this.mExitOnEnd, loopOnEnd: this.mLoopOnEnd, @@ -87,7 +97,7 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { bkmodeEnabled: this.mBkmodeEnabled, showControls: this.mShowControls, displayMode: this.mDisplayMode, - componentTag: 'app-fullscreen', + componentTag: 'picsa-manual-activity-details', }); console.log(`res ${JSON.stringify(res)}`); if (!res.result && (this.platform === 'ios' || this.platform === 'android')) { @@ -99,146 +109,139 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { } } } - private async addListenersToPlayerPlugin(): Promise { - this.handlerPlay = await this.videoPlayer.addListener( - 'jeepCapVideoPlayerPlay', - (data: any) => this.playerPlay(data), - false - ); - this.handlerPause = await this.videoPlayer.addListener( - 'jeepCapVideoPlayerPause', - (data: any) => this.playerPause(data), - false - ); - this.handlerEnded = await this.videoPlayer.addListener( - 'jeepCapVideoPlayerEnded', - (data: any) => this.playerEnd(data), - false - ); - this.handlerExit = await this.videoPlayer.addListener( - 'jeepCapVideoPlayerExit', - (data: any) => this.playerExit(data), - false - ); - this.handlerReady = await this.videoPlayer.addListener( - 'jeepCapVideoPlayerReady', - async (data: any) => this.playerReady(data), - false - ); - return; - } - private async playerPlay(data: any): Promise { - console.log(`Event jeepCapVideoPlayerPlay ${data}`); - return; - } - private async playerPause(data: any): Promise { - console.log(`Event jeepCapVideoPlayerPause ${data}`); - return; - } - private async playerEnd(data: any): Promise { - console.log(`Event jeepCapVideoPlayerEnded ${data}`); - // await this.leaveModal(); - return; - } - private async playerExit(data: any): Promise { - console.log(`Event jeepCapVideoPlayerExit ${data}`); - // await this.leaveModal(); - return; - } - private async playerReady(data: any): Promise { - console.log(`Event jeepCapVideoPlayerReady ${data}`); - console.log(`testVideoPlayerPlugin testAPI ${this.mTestApi}`); - console.log(`testVideoPlayerPlugin first ${this.first}`); - if (this.mTestApi && this.first) { - // test the API - this.first = false; - console.log('testVideoPlayerPlugin calling isPlaying '); - let isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); - console.log(` isPlaying ${isPlaying}`); - this.apiTimer1 = setTimeout(async () => { - let pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); - console.log(`pause ${pause}`); - let retRate: any = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); - console.log(`rate ${retRate.value}`); - retRate = await this.videoPlayer.setRate({ playerId: 'fullscreen', rate: 0.5 }); - console.log(`new rate ${retRate.value}`); - isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); - console.log(`const isPlaying after pause ${isPlaying}`); - const currentTime = await this.videoPlayer.getCurrentTime({ playerId: 'fullscreen' }); - console.log('const currentTime ', currentTime); - let muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); - if (muted.value) { - console.log('getMuted true'); - } else { - console.log('getMuted false'); - } - let setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: !muted.value }); - if (setMuted.value) { - console.log('setMuted true'); - } else { - console.log('setMuted false'); - } - muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); - if (muted.value) { - console.log('getMuted true'); - } else { - console.log('getMuted false'); - } - let duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); - console.log(`duration ${duration}`); - // valid for movies havin a duration > 25 - const seektime = - currentTime.value + 0.5 * duration.value < duration.value - 25 - ? currentTime.value + 0.5 * duration.value - : duration.value - 25; - let setCurrentTime = await this.videoPlayer.setCurrentTime({ playerId: 'fullscreen', seektime }); - console.log('setCurrentTime ', setCurrentTime.value); - let play = await this.videoPlayer.play({ playerId: 'fullscreen' }); - console.log(`$$$ play ${play}`); - retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); - console.log(`$$$ rate ${retRate.value}`); - this.apiTimer2 = setTimeout(async () => { - setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: false }); - console.log('setMuted ', setMuted); - const setVolume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 0.5 }); - console.log(`setVolume ${setVolume}`); - let volume = await this.videoPlayer.getVolume({ playerId: 'fullscreen' }); - console.log(`Volume ${volume}`); - this.apiTimer3 = setTimeout(async () => { - pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); - console.log('const pause ', pause); - duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); - console.log(`duration ${duration}`); - volume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 1.0 }); - console.log(`Volume ${volume}`); - setCurrentTime = await this.videoPlayer.setCurrentTime({ - playerId: 'fullscreen', - seektime: duration.value - 3, - }); - console.log(`setCurrentTime ${setCurrentTime}`); - play = await this.videoPlayer.play({ playerId: 'fullscreen' }); - console.log(`xxx play ${play}`); - retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); - console.log(`xxx rate ${retRate.value}`); - }, 10000); - }, 8000); - }, 7000); - } - return; - } + // private async addListenersToPlayerPlugin(): Promise { + // this.handlerPlay = await this.videoPlayer.addListener( + // 'jeepCapVideoPlayerPlay', + // (data: any) => this.playerPlay(data), + // false + // ); + // this.handlerPause = await this.videoPlayer.addListener( + // 'jeepCapVideoPlayerPause', + // (data: any) => this.playerPause(data), + // false + // ); + // this.handlerEnded = await this.videoPlayer.addListener( + // 'jeepCapVideoPlayerEnded', + // (data: any) => this.playerEnd(data), + // false + // ); + // this.handlerExit = await this.videoPlayer.addListener( + // 'jeepCapVideoPlayerExit', + // (data: any) => this.playerExit(data), + // false + // ); + // this.handlerReady = await this.videoPlayer.addListener( + // 'jeepCapVideoPlayerReady', + // async (data: any) => this.playerReady(data), + // false + // ); + // return; + // } + // private async playerPlay(data: any): Promise { + // return; + // } + // private async playerPause(data: any): Promise { + // return; + // } + // private async playerEnd(data: any): Promise { + // return; + // } + // private async playerExit(data: any): Promise { + // return; + // } + // private async playerReady(data: any): Promise { + // console.log(`Event jeepCapVideoPlayerReady ${data}`); + // console.log(`testVideoPlayerPlugin testAPI ${this.mTestApi}`); + // console.log(`testVideoPlayerPlugin first ${this.first}`); + // if (this.mTestApi && this.first) { + // // test the API + // this.first = false; + // console.log('testVideoPlayerPlugin calling isPlaying '); + // let isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); + // console.log(` isPlaying ${isPlaying}`); + // this.apiTimer1 = setTimeout(async () => { + // let pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); + // console.log(`pause ${pause}`); + // let retRate: any = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); + // console.log(`rate ${retRate.value}`); + // retRate = await this.videoPlayer.setRate({ playerId: 'fullscreen', rate: 0.5 }); + // console.log(`new rate ${retRate.value}`); + // isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); + // console.log(`const isPlaying after pause ${isPlaying}`); + // const currentTime = await this.videoPlayer.getCurrentTime({ playerId: 'fullscreen' }); + // console.log('const currentTime ', currentTime); + // let muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); + // if (muted.value) { + // console.log('getMuted true'); + // } else { + // console.log('getMuted false'); + // } + // let setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: !muted.value }); + // if (setMuted.value) { + // console.log('setMuted true'); + // } else { + // console.log('setMuted false'); + // } + // muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); + // if (muted.value) { + // console.log('getMuted true'); + // } else { + // console.log('getMuted false'); + // } + // let duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); + // console.log(`duration ${duration}`); + // // valid for movies havin a duration > 25 + // const seektime = + // currentTime.value + 0.5 * duration.value < duration.value - 25 + // ? currentTime.value + 0.5 * duration.value + // : duration.value - 25; + // let setCurrentTime = await this.videoPlayer.setCurrentTime({ playerId: 'fullscreen', seektime }); + // console.log('setCurrentTime ', setCurrentTime.value); + // let play = await this.videoPlayer.play({ playerId: 'fullscreen' }); + // console.log(`$$$ play ${play}`); + // retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); + // console.log(`$$$ rate ${retRate.value}`); + // this.apiTimer2 = setTimeout(async () => { + // setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: false }); + // console.log('setMuted ', setMuted); + // const setVolume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 0.5 }); + // console.log(`setVolume ${setVolume}`); + // let volume = await this.videoPlayer.getVolume({ playerId: 'fullscreen' }); + // console.log(`Volume ${volume}`); + // this.apiTimer3 = setTimeout(async () => { + // pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); + // console.log('const pause ', pause); + // duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); + // console.log(`duration ${duration}`); + // volume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 1.0 }); + // console.log(`Volume ${volume}`); + // setCurrentTime = await this.videoPlayer.setCurrentTime({ + // playerId: 'fullscreen', + // seektime: duration.value - 3, + // }); + // console.log(`setCurrentTime ${setCurrentTime}`); + // play = await this.videoPlayer.play({ playerId: 'fullscreen' }); + // console.log(`xxx play ${play}`); + // retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); + // console.log(`xxx rate ${retRate.value}`); + // }, 10000); + // }, 8000); + // }, 7000); + // } + // return; + // } async ngOnDestroy() { - const res: any = await this.videoPlayer.stopAllPlayers(); - clearTimeout(this.apiTimer3); - clearTimeout(this.apiTimer2); - clearTimeout(this.apiTimer1); - this.handlerPlay.remove(); - this.handlerPause.remove(); - this.handlerEnded.remove(); - this.handlerReady.remove(); - this.handlerPlaying.remove(); - this.handlerExit.remove(); + // clearTimeout(this.apiTimer3); + // clearTimeout(this.apiTimer2); + // clearTimeout(this.apiTimer1); + // this.handlerPlay.remove(); + // this.handlerPause.remove(); + // this.handlerEnded.remove(); + // this.handlerReady.remove(); + // this.handlerPlaying.remove(); + // this.handlerExit.remove(); } } diff --git a/apps/picsa-tools/manual-tool/src/app/service/video-player.ts b/apps/picsa-tools/manual-tool/src/app/utils/video-player.ts similarity index 100% rename from apps/picsa-tools/manual-tool/src/app/service/video-player.ts rename to apps/picsa-tools/manual-tool/src/app/utils/video-player.ts From e7bba609930a6ba4cf2ba6547d0ceb72d33b0f80 Mon Sep 17 00:00:00 2001 From: khalifan-kfan Date: Mon, 24 Jul 2023 15:10:13 +0300 Subject: [PATCH 03/10] make video full screen display to support more devices --- .../activity-details.component.html | 10 ++++++---- .../activity-details.component.scss | 13 +++++++++++-- .../activity-details/activity-details.component.ts | 10 ++++++++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html index 64c9cf1de..325a6a780 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html @@ -2,21 +2,23 @@

{{ activity?.label }}

+
+ play_circle_outline +
-
- +
{{ 'Info Sheet' | translate }}
- +
{{ 'Create' | translate }}
- +
{{ 'Quiz' | translate }}
diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss index 710f66645..2ceff35e2 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss @@ -9,12 +9,21 @@ h2{ margin-bottom: 2rem; } -.video-player{ +.guide-video-placeholder{ width: 70%; margin-bottom: 2rem; + height: 20rem; display: flex; align-items: center; justify-content: center; + background-color: black; +} +.play-button{ + display: flex; + justify-content: center; + align-items: center; + height: 4rem; + width: 4rem; } .svg-row{ display: flex; @@ -24,7 +33,7 @@ h2{ justify-content: space-evenly; align-items: center; } -mat-icon{ +.row-mat-icon{ height: 3rem; width: 3rem; } diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts index 553bf01ed..43c5d1df6 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts @@ -67,10 +67,16 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { this.videoPlayer = player.plugin; - await this.intiateVideoPlayer() + //await this.intiateVideoPlayer() //await this.addListenersToPlayerPlugin(); } + + + async playVideo (){ + await this.intiateVideoPlayer(); + } + async intiateVideoPlayer() { this.mUrl = this.activity?.video; this.mStoptions = this.stoptions; @@ -86,7 +92,7 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { this.first = true; } const res: any = await this.videoPlayer.initPlayer({ - mode: 'embedded',// or fullscreen (2 modes) + mode: 'fullscreen',// or embedded (2 modes) url: this.mUrl, subtitleOptions: this.mStoptions, playerId: 'video-player', From d49de6a5de9c7654c83ad10e496dd791ffaaec4a Mon Sep 17 00:00:00 2001 From: khalifan-kfan Date: Mon, 24 Jul 2023 15:18:16 +0300 Subject: [PATCH 04/10] format edits --- .../activity-details.component.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts index 43c5d1df6..525e87f1e 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts @@ -238,16 +238,16 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { // } - async ngOnDestroy() { - const res: any = await this.videoPlayer.stopAllPlayers(); - // clearTimeout(this.apiTimer3); - // clearTimeout(this.apiTimer2); - // clearTimeout(this.apiTimer1); - // this.handlerPlay.remove(); - // this.handlerPause.remove(); - // this.handlerEnded.remove(); - // this.handlerReady.remove(); - // this.handlerPlaying.remove(); - // this.handlerExit.remove(); -} + async ngOnDestroy() { + const res: any = await this.videoPlayer.stopAllPlayers(); + // clearTimeout(this.apiTimer3); + // clearTimeout(this.apiTimer2); + // clearTimeout(this.apiTimer1); + // this.handlerPlay.remove(); + // this.handlerPause.remove(); + // this.handlerEnded.remove(); + // this.handlerReady.remove(); + // this.handlerPlaying.remove(); + // this.handlerExit.remove(); + } } From d19852ce9fc77b009852d2751424eefd310bfdce Mon Sep 17 00:00:00 2001 From: chrismclarke Date: Mon, 18 Sep 2023 22:51:04 -0700 Subject: [PATCH 05/10] refactor: video player shared component --- .../activity-details.component.html | 7 +- .../activity-details.component.scss | 67 ++--- .../activity-details.component.ts | 236 +----------------- .../src/app/pages/activity/activity.module.ts | 10 +- .../manual-tool/src/app/utils/video-player.ts | 8 - libs/shared/src/features/index.ts | 1 + .../shared/src/features/video-player/index.ts | 17 ++ .../video-player/video-player.component.html | 6 + .../video-player/video-player.component.scss | 42 ++++ .../video-player.component.spec.ts | 21 ++ .../video-player/video-player.component.ts | 127 ++++++++++ libs/theme/src/themes/picsa-global.scss | 1 + libs/theme/src/themes/picsa-mw.scss | 1 + libs/theme/src/themes/picsa-tj.scss | 1 + libs/theme/src/themes/picsa-zm.scss | 1 + 15 files changed, 255 insertions(+), 291 deletions(-) delete mode 100644 apps/picsa-tools/manual-tool/src/app/utils/video-player.ts create mode 100644 libs/shared/src/features/video-player/index.ts create mode 100644 libs/shared/src/features/video-player/video-player.component.html create mode 100644 libs/shared/src/features/video-player/video-player.component.scss create mode 100644 libs/shared/src/features/video-player/video-player.component.spec.ts create mode 100644 libs/shared/src/features/video-player/video-player.component.ts diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html index 325a6a780..db000adbd 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.html @@ -1,12 +1,7 @@

{{ activity?.label }}

- -
- play_circle_outline -
- -
+
diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss index 2ceff35e2..7d383e64c 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.scss @@ -1,47 +1,30 @@ -.page-container{ - padding-left: 1rem; - padding-right: 1rem; - width: 90%; - display: flex; - align-items: center; - flex-direction: column; +.page-container { + padding-left: 1rem; + padding-right: 1rem; + width: 90%; + display: flex; + align-items: center; + flex-direction: column; } -h2{ - margin-bottom: 2rem; +h2 { + margin-bottom: 2rem; } -.guide-video-placeholder{ - width: 70%; - margin-bottom: 2rem; - height: 20rem; - display: flex; - align-items: center; - justify-content: center; - background-color: black; +.svg-row { + display: flex; + flex-direction: row; + width: 100%; + margin-top: 3rem; + justify-content: space-evenly; + align-items: center; } -.play-button{ - display: flex; - justify-content: center; - align-items: center; - height: 4rem; - width: 4rem; -} -.svg-row{ - display: flex; - flex-direction: row; - width: 100%; - margin-top: 3rem; - justify-content: space-evenly; - align-items: center; -} -.row-mat-icon{ - height: 3rem; - width: 3rem; +.row-mat-icon { + height: 3rem; + width: 3rem; } - -.svg-item{ - flex-direction: column; - display: flex; - align-items: center; - gap:.5rem -} \ No newline at end of file +.svg-item { + flex-direction: column; + display: flex; + align-items: center; + gap: 0.5rem; +} diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts index 525e87f1e..63ce7e4db 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity-details/activity-details.component.ts @@ -1,60 +1,15 @@ -import { Component, Input, OnDestroy,OnInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { IManualActivity, PICSA_MANUAL_GRID_DATA_EXTENSION } from '../../data/manual-contents'; -import { setVideoPlayer } from '../../utils/video-player'; @Component({ selector: 'picsa-manual-activity-details', templateUrl: './activity-details.component.html', styleUrls: ['./activity-details.component.scss'], }) -export class ActivityDetailsComponent implements OnInit, OnDestroy { +export class ActivityDetailsComponent implements OnInit { activity?: IManualActivity; - @Input() url: string; - @Input() sturl: string; - @Input() stlang: string; - @Input() stoptions: any; - @Input() rate: number; - @Input() exitOnEnd: boolean; - @Input() loopOnEnd: boolean; - @Input() pipEnabled: boolean; - @Input() bkmodeEnabled: boolean; - @Input() showControls: boolean; - @Input() displayMode: string; - @Input() testApi: boolean; - @Input() platform: string; - - private videoPlayer: any; - - //most of the code commented out is concerned with listeners - // Todo: determine if it will be required or not - - // private handlerPlay: any; - // private handlerPause: any; - // private handlerEnded: any; - // private handlerReady: any; - // private handlerPlaying: any; - // private handlerExit: any; - private first = false; - - // private mSturl: string = null; - // private mStlang: string = null; - - // private apiTimer1: any; - // private apiTimer2: any; - // private apiTimer3: any; - - private mUrl: any = null; - private mStoptions: any = null; - private mRate = 1.0; - private mExitOnEnd = true; - private mLoopOnEnd = false; - private mPipEnabled = true; - private mBkmodeEnabled = true; - private mShowControls = true; - private mDisplayMode = 'portrait'; - private mTestApi: boolean; constructor(private route: ActivatedRoute) {} async ngOnInit() { @@ -62,192 +17,5 @@ export class ActivityDetailsComponent implements OnInit, OnDestroy { if (activityId) { this.activity = PICSA_MANUAL_GRID_DATA_EXTENSION.find((activity) => activity.id === activityId); } - this.mTestApi = this.testApi ? this.testApi : false; - const player: any = await setVideoPlayer(); - - this.videoPlayer = player.plugin; - - //await this.intiateVideoPlayer() - - //await this.addListenersToPlayerPlugin(); } - - - async playVideo (){ - await this.intiateVideoPlayer(); - } - - async intiateVideoPlayer() { - this.mUrl = this.activity?.video; - this.mStoptions = this.stoptions; - this.mRate = this.rate; - this.mExitOnEnd = this.exitOnEnd; - this.mLoopOnEnd = this.loopOnEnd; - this.mPipEnabled = this.pipEnabled; - this.mBkmodeEnabled = this.bkmodeEnabled; - this.mShowControls = this.showControls; - this.mDisplayMode = this.displayMode; - if (this.mUrl != null && this.mUrl != undefined) { - if (this.mTestApi) { - this.first = true; - } - const res: any = await this.videoPlayer.initPlayer({ - mode: 'fullscreen',// or embedded (2 modes) - url: this.mUrl, - subtitleOptions: this.mStoptions, - playerId: 'video-player', - rate: this.mRate, - exitOnEnd: this.mExitOnEnd, - loopOnEnd: this.mLoopOnEnd, - pipEnabled: this.mPipEnabled, - bkmodeEnabled: this.mBkmodeEnabled, - showControls: this.mShowControls, - displayMode: this.mDisplayMode, - componentTag: 'picsa-manual-activity-details', - }); - console.log(`res ${JSON.stringify(res)}`); - if (!res.result && (this.platform === 'ios' || this.platform === 'android')) { - console.log(res.message); - } - console.log('res.result ', res.result); - if (!res.result) { - console.log(`res.message ${res.message}`); - } - } - } - // private async addListenersToPlayerPlugin(): Promise { - // this.handlerPlay = await this.videoPlayer.addListener( - // 'jeepCapVideoPlayerPlay', - // (data: any) => this.playerPlay(data), - // false - // ); - // this.handlerPause = await this.videoPlayer.addListener( - // 'jeepCapVideoPlayerPause', - // (data: any) => this.playerPause(data), - // false - // ); - // this.handlerEnded = await this.videoPlayer.addListener( - // 'jeepCapVideoPlayerEnded', - // (data: any) => this.playerEnd(data), - // false - // ); - // this.handlerExit = await this.videoPlayer.addListener( - // 'jeepCapVideoPlayerExit', - // (data: any) => this.playerExit(data), - // false - // ); - // this.handlerReady = await this.videoPlayer.addListener( - // 'jeepCapVideoPlayerReady', - // async (data: any) => this.playerReady(data), - // false - // ); - // return; - // } - // private async playerPlay(data: any): Promise { - // return; - // } - // private async playerPause(data: any): Promise { - // return; - // } - // private async playerEnd(data: any): Promise { - // return; - // } - // private async playerExit(data: any): Promise { - // return; - // } - // private async playerReady(data: any): Promise { - // console.log(`Event jeepCapVideoPlayerReady ${data}`); - // console.log(`testVideoPlayerPlugin testAPI ${this.mTestApi}`); - // console.log(`testVideoPlayerPlugin first ${this.first}`); - // if (this.mTestApi && this.first) { - // // test the API - // this.first = false; - // console.log('testVideoPlayerPlugin calling isPlaying '); - // let isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); - // console.log(` isPlaying ${isPlaying}`); - // this.apiTimer1 = setTimeout(async () => { - // let pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); - // console.log(`pause ${pause}`); - // let retRate: any = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); - // console.log(`rate ${retRate.value}`); - // retRate = await this.videoPlayer.setRate({ playerId: 'fullscreen', rate: 0.5 }); - // console.log(`new rate ${retRate.value}`); - // isPlaying = await this.videoPlayer.isPlaying({ playerId: 'fullscreen' }); - // console.log(`const isPlaying after pause ${isPlaying}`); - // const currentTime = await this.videoPlayer.getCurrentTime({ playerId: 'fullscreen' }); - // console.log('const currentTime ', currentTime); - // let muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); - // if (muted.value) { - // console.log('getMuted true'); - // } else { - // console.log('getMuted false'); - // } - // let setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: !muted.value }); - // if (setMuted.value) { - // console.log('setMuted true'); - // } else { - // console.log('setMuted false'); - // } - // muted = await this.videoPlayer.getMuted({ playerId: 'fullscreen' }); - // if (muted.value) { - // console.log('getMuted true'); - // } else { - // console.log('getMuted false'); - // } - // let duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); - // console.log(`duration ${duration}`); - // // valid for movies havin a duration > 25 - // const seektime = - // currentTime.value + 0.5 * duration.value < duration.value - 25 - // ? currentTime.value + 0.5 * duration.value - // : duration.value - 25; - // let setCurrentTime = await this.videoPlayer.setCurrentTime({ playerId: 'fullscreen', seektime }); - // console.log('setCurrentTime ', setCurrentTime.value); - // let play = await this.videoPlayer.play({ playerId: 'fullscreen' }); - // console.log(`$$$ play ${play}`); - // retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); - // console.log(`$$$ rate ${retRate.value}`); - // this.apiTimer2 = setTimeout(async () => { - // setMuted = await this.videoPlayer.setMuted({ playerId: 'fullscreen', muted: false }); - // console.log('setMuted ', setMuted); - // const setVolume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 0.5 }); - // console.log(`setVolume ${setVolume}`); - // let volume = await this.videoPlayer.getVolume({ playerId: 'fullscreen' }); - // console.log(`Volume ${volume}`); - // this.apiTimer3 = setTimeout(async () => { - // pause = await this.videoPlayer.pause({ playerId: 'fullscreen' }); - // console.log('const pause ', pause); - // duration = await this.videoPlayer.getDuration({ playerId: 'fullscreen' }); - // console.log(`duration ${duration}`); - // volume = await this.videoPlayer.setVolume({ playerId: 'fullscreen', volume: 1.0 }); - // console.log(`Volume ${volume}`); - // setCurrentTime = await this.videoPlayer.setCurrentTime({ - // playerId: 'fullscreen', - // seektime: duration.value - 3, - // }); - // console.log(`setCurrentTime ${setCurrentTime}`); - // play = await this.videoPlayer.play({ playerId: 'fullscreen' }); - // console.log(`xxx play ${play}`); - // retRate = await this.videoPlayer.getRate({ playerId: 'fullscreen' }); - // console.log(`xxx rate ${retRate.value}`); - // }, 10000); - // }, 8000); - // }, 7000); - // } - // return; - // } - - - async ngOnDestroy() { - const res: any = await this.videoPlayer.stopAllPlayers(); - // clearTimeout(this.apiTimer3); - // clearTimeout(this.apiTimer2); - // clearTimeout(this.apiTimer1); - // this.handlerPlay.remove(); - // this.handlerPause.remove(); - // this.handlerEnded.remove(); - // this.handlerReady.remove(); - // this.handlerPlaying.remove(); - // this.handlerExit.remove(); - } } diff --git a/apps/picsa-tools/manual-tool/src/app/pages/activity/activity.module.ts b/apps/picsa-tools/manual-tool/src/app/pages/activity/activity.module.ts index 947c28f7c..bea726e36 100644 --- a/apps/picsa-tools/manual-tool/src/app/pages/activity/activity.module.ts +++ b/apps/picsa-tools/manual-tool/src/app/pages/activity/activity.module.ts @@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { MatIconModule } from '@angular/material/icon'; import { Route, RouterModule } from '@angular/router'; +import { PicsaVideoPlayerModule } from '@picsa/shared/features'; import { PicsaTranslateModule } from '@picsa/shared/modules'; import { ManualToolComponentsModule } from '../../components/components.module'; @@ -20,7 +21,14 @@ const routes: Route[] = [ ]; @NgModule({ - imports: [CommonModule, ManualToolComponentsModule,MatIconModule, RouterModule.forChild(routes), PicsaTranslateModule], + imports: [ + CommonModule, + ManualToolComponentsModule, + MatIconModule, + RouterModule.forChild(routes), + PicsaTranslateModule, + PicsaVideoPlayerModule, + ], exports: [], declarations: [ActivityComponent, ActivityDetailsComponent], providers: [], diff --git a/apps/picsa-tools/manual-tool/src/app/utils/video-player.ts b/apps/picsa-tools/manual-tool/src/app/utils/video-player.ts deleted file mode 100644 index 62d2f463e..000000000 --- a/apps/picsa-tools/manual-tool/src/app/utils/video-player.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Capacitor } from '@capacitor/core'; -import { CapacitorVideoPlayer } from 'capacitor-video-player'; - -export const setVideoPlayer = async (): Promise=> { - const platform = Capacitor.getPlatform(); - //console.log(CapacitorVideoPlayer) - return {plugin:CapacitorVideoPlayer, platform}; -}; diff --git a/libs/shared/src/features/index.ts b/libs/shared/src/features/index.ts index df7651d2a..65cfd6283 100644 --- a/libs/shared/src/features/index.ts +++ b/libs/shared/src/features/index.ts @@ -2,3 +2,4 @@ export * from './animations'; export * from './charts'; export * from './dialog'; export * from './map'; +export * from './video-player'; diff --git a/libs/shared/src/features/video-player/index.ts b/libs/shared/src/features/video-player/index.ts new file mode 100644 index 000000000..ef1603137 --- /dev/null +++ b/libs/shared/src/features/video-player/index.ts @@ -0,0 +1,17 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; + +import { VideoPlayerComponent } from './video-player.component'; + +@NgModule({ + imports: [CommonModule, MatButtonModule, MatIconModule], + exports: [VideoPlayerComponent], + declarations: [VideoPlayerComponent], + providers: [], +}) +/** + * Provide a `` component that plays videos on web or native device + */ +export class PicsaVideoPlayerModule {} diff --git a/libs/shared/src/features/video-player/video-player.component.html b/libs/shared/src/features/video-player/video-player.component.html new file mode 100644 index 000000000..449f9572d --- /dev/null +++ b/libs/shared/src/features/video-player/video-player.component.html @@ -0,0 +1,6 @@ +
+ +

No Video Selected

+
diff --git a/libs/shared/src/features/video-player/video-player.component.scss b/libs/shared/src/features/video-player/video-player.component.scss new file mode 100644 index 000000000..60efb0e42 --- /dev/null +++ b/libs/shared/src/features/video-player/video-player.component.scss @@ -0,0 +1,42 @@ +@use '@angular/material' as mat; + +:host { + display: contents; +} +.placeholder { + position: relative; + width: 100%; + max-width: 480px; + margin-bottom: 2rem; + aspect-ratio: 16/9; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(0, 0, 0, 0.25); +} +$icon-size: 3rem; +.play-button { + position: absolute; + z-index: 3; + height: calc($icon-size + 1rem); + width: calc($icon-size + 1rem); + padding: 0.5rem; + display: flex; + justify-content: center; + align-items: center; + mat-icon { + height: $icon-size; + width: $icon-size; + font-size: $icon-size; + } +} +.error-message { + position: absolute; + top: 8px; + padding: 8px; + text-align: center; + font-weight: bold; + border-radius: 4px; + background: #ffffff; + color: var(--color-warn); +} diff --git a/libs/shared/src/features/video-player/video-player.component.spec.ts b/libs/shared/src/features/video-player/video-player.component.spec.ts new file mode 100644 index 000000000..117bbba91 --- /dev/null +++ b/libs/shared/src/features/video-player/video-player.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { VideoPlayerComponent } from './video-player.component'; + +describe('VideoPlayerComponent', () => { + let component: VideoPlayerComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [VideoPlayerComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(VideoPlayerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/libs/shared/src/features/video-player/video-player.component.ts b/libs/shared/src/features/video-player/video-player.component.ts new file mode 100644 index 000000000..f15d176d1 --- /dev/null +++ b/libs/shared/src/features/video-player/video-player.component.ts @@ -0,0 +1,127 @@ +import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core'; +import { Capacitor } from '@capacitor/core'; +import { CapacitorVideoPlayer, CapacitorVideoPlayerPlugin, capVideoPlayerOptions } from 'capacitor-video-player'; + +// Fix listeners missing from type +// https://github.com/jepiqueau/capacitor-video-player/blob/master/docs/API.md#listeners +type IVideoEvent = + | 'jeepCapVideoPlayerReady' + | 'jeepCapVideoPlayerPlay' + | 'jeepCapVideoPlayerPause' + | 'jeepCapVideoPlayerEnded' + | 'jeepCapVideoPlayerExit'; +interface capVideoListener { + playerId: string; + currentTime: number; +} +interface IVideoPlayer extends CapacitorVideoPlayerPlugin { + addListener: (event: IVideoEvent, callback: (data: capVideoListener) => void) => void; + removeListener: (event: IVideoEvent, callback: (data: capVideoListener) => void) => void; +} + +@Component({ + selector: 'picsa-video-player', + templateUrl: './video-player.component.html', + styleUrls: ['./video-player.component.scss'], +}) +export class VideoPlayerComponent implements AfterViewInit, OnDestroy { + /** Optional override of player options */ + @Input() options: Partial = {}; + /** Url of video to player */ + @Input() url?: string; + /** Unique identifier used in case of multiple players*/ + protected playerId = `videoPlayer${generateID(5)}`; + + protected showPlayButton = false; + + public videoPlayer = CapacitorVideoPlayer as IVideoPlayer; + + private playerOptions: capVideoPlayerOptions; + + async ngAfterViewInit() { + // Automatically init after page loaded so that preview can be generated + this.initPlayer(); + } + + async ngOnDestroy() { + await this.videoPlayer.stopAllPlayers(); + this.removeListeners(); + } + + public async playVideo() { + await this.videoPlayer.play({ playerId: this.playerId }); + } + + private async initPlayer() { + const defaultOptions: capVideoPlayerOptions = { + mode: 'embedded', + url: this.url, + playerId: this.playerId, + componentTag: 'picsa-video-player', + exitOnEnd: false, + width: 480, + height: 270, + displayMode: 'landscape', + }; + if (Capacitor.isNativePlatform()) { + defaultOptions.mode = 'fullscreen'; + defaultOptions.exitOnEnd = true; + } + // Merge default options with user override + this.playerOptions = { ...defaultOptions, ...this.options }; + await this.videoPlayer.initPlayer(this.playerOptions); + this.addListeners(); + } + + /********************************************************************************* + * Events + * Various play start/stop events can be listened to, with player id and time returned + * Currently mostly just used for toggling play button display + *********************************************************************************/ + + /** + * Add listener for play events + * Use named functions to allow removal on destroy + */ + private addListeners() { + this.videoPlayer.addListener('jeepCapVideoPlayerReady', this.handlePlayerReady.bind(this)); + this.videoPlayer.addListener('jeepCapVideoPlayerPlay', this.handlePlayerPlay.bind(this)); + this.videoPlayer.addListener('jeepCapVideoPlayerPause', this.handlePlayerPause.bind(this)); + this.videoPlayer.addListener('jeepCapVideoPlayerEnded', this.handlePlayerEnded.bind(this)); + this.videoPlayer.addListener('jeepCapVideoPlayerExit', this.handlePlayerExit.bind(this)); + } + + /** Remove all event listeners */ + private removeListeners() { + this.videoPlayer.removeListener('jeepCapVideoPlayerReady', this.handlePlayerReady); + this.videoPlayer.removeListener('jeepCapVideoPlayerPlay', this.handlePlayerPlay); + this.videoPlayer.removeListener('jeepCapVideoPlayerPause', this.handlePlayerPause); + this.videoPlayer.removeListener('jeepCapVideoPlayerEnded', this.handlePlayerEnded); + this.videoPlayer.removeListener('jeepCapVideoPlayerExit', this.handlePlayerExit); + } + private handlePlayerReady() { + this.showPlayButton = true; + } + private handlePlayerPlay() { + this.showPlayButton = false; + } + private handlePlayerPause() { + this.showPlayButton = true; + } + + private handlePlayerEnded() { + this.showPlayButton = true; + } + private handlePlayerExit() { + this.showPlayButton = true; + } +} + +// HACK - adapted from db method +function generateID(length = 20, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') { + let autoId = ''; + for (let i = 0; i < length; i++) { + autoId += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return autoId; +} diff --git a/libs/theme/src/themes/picsa-global.scss b/libs/theme/src/themes/picsa-global.scss index a19518e9a..b73705103 100644 --- a/libs/theme/src/themes/picsa-global.scss +++ b/libs/theme/src/themes/picsa-global.scss @@ -88,6 +88,7 @@ body[data-theme='picsa-global'] { --color-primary: #{map-get($palette-primary, 500)}; --color-primary-50: #{map-get($palette-primary, 50)}; --color-secondary: #{map-get($palette-accent, 500)}; + --color-warn: #{map-get($palette-warn, 500)}; --color-black: #1a2138; --color-light: #d8d8d8; --color-white: #ffffff; diff --git a/libs/theme/src/themes/picsa-mw.scss b/libs/theme/src/themes/picsa-mw.scss index a75555ef0..fb0cd9c74 100644 --- a/libs/theme/src/themes/picsa-mw.scss +++ b/libs/theme/src/themes/picsa-mw.scss @@ -88,6 +88,7 @@ body[data-theme='picsa-mw'] { --color-primary: #{map-get($palette-primary, 500)}; --color-primary-50: #{map-get($palette-primary, 50)}; --color-secondary: #{map-get($palette-accent, 500)}; + --color-warn: #{map-get($palette-warn, 500)}; --color-black: #1a2138; --color-light: #d8d8d8; --color-white: #ffffff; diff --git a/libs/theme/src/themes/picsa-tj.scss b/libs/theme/src/themes/picsa-tj.scss index 06d3811b9..23b690eea 100644 --- a/libs/theme/src/themes/picsa-tj.scss +++ b/libs/theme/src/themes/picsa-tj.scss @@ -88,6 +88,7 @@ body[data-theme='picsa-tj'] { --color-primary: #{map-get($palette-primary, 500)}; --color-primary-50: #{map-get($palette-primary, 50)}; --color-secondary: #{map-get($palette-accent, 500)}; + --color-warn: #{map-get($palette-warn, 500)}; --color-black: #1a2138; --color-light: #d8d8d8; --color-white: #ffffff; diff --git a/libs/theme/src/themes/picsa-zm.scss b/libs/theme/src/themes/picsa-zm.scss index f9474dc7e..d3b0b3098 100644 --- a/libs/theme/src/themes/picsa-zm.scss +++ b/libs/theme/src/themes/picsa-zm.scss @@ -88,6 +88,7 @@ body[data-theme='picsa-zm'] { --color-primary: #{map-get($palette-primary, 500)}; --color-primary-50: #{map-get($palette-primary, 50)}; --color-secondary: #{map-get($palette-accent, 500)}; + --color-warn: #{map-get($palette-warn, 500)}; --color-black: #1a2138; --color-light: #d8d8d8; --color-white: #ffffff; From d1a351107820e1d8f28dc2f43b9d51084d5e7ec8 Mon Sep 17 00:00:00 2001 From: chrismclarke Date: Mon, 18 Sep 2023 22:53:31 -0700 Subject: [PATCH 06/10] chore: add video player to capacitor config --- .../android/.idea/misc.xml | 1 - .../android/app/capacitor.build.gradle | 1 + .../app/src/main/assets/capacitor.config.json | 53 ++++++++++--------- .../src/main/assets/capacitor.plugins.json | 4 ++ .../android/capacitor.settings.gradle | 3 ++ .../extension-app-native/capacitor.config.ts | 1 + 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/apps/picsa-apps/extension-app-native/android/.idea/misc.xml b/apps/picsa-apps/extension-app-native/android/.idea/misc.xml index 9e1d58b02..fdc12d097 100644 --- a/apps/picsa-apps/extension-app-native/android/.idea/misc.xml +++ b/apps/picsa-apps/extension-app-native/android/.idea/misc.xml @@ -1,4 +1,3 @@ -