1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16const curves = requireNativeModule('ohos.curves'); 17const PiPWindow = requireNapi('PiPWindow'); 18const pip = requireNapi('pip'); 19 20const TAG = "PiPVideo"; 21const TIMEOUT = 3e3; 22 23export class PiPVideo extends ViewPU { 24 constructor(e, t, o, i = -1, n = void 0) { 25 super(e, o, i); 26 "function" == typeof n && (this.paramsGenerator_ = n); 27 this.xComponentId = "pip"; 28 this.windowType = PiPWindow.PiPTemplateType.VIDEO_PLAY; 29 this.hideEventId = -1; 30 this.__showControl = new ObservedPropertySimplePU(!1, this, "showControl"); 31 this.xComponentController = new XComponentController; 32 this.surfaceId = ""; 33 this.controlTransEffect = TransitionEffect.OPACITY; 34 this.__hideControlNow = new ObservedPropertySimplePU(!1, this, "hideControlNow"); 35 this.addProvidedVar("hideControlNow", this.__hideControlNow); 36 this.__hideControlDelay = new ObservedPropertySimplePU(!1, this, "hideControlDelay"); 37 this.addProvidedVar("hideControlDelay", this.__hideControlDelay); 38 this.setInitiallyProvidedValue(t); 39 this.declareWatch("hideControlNow", this.onHideControlNow); 40 this.declareWatch("hideControlDelay", this.onHideControlDelay) 41 } 42 43 setInitiallyProvidedValue(e) { 44 void 0 !== e.xComponentId && (this.xComponentId = e.xComponentId); 45 void 0 !== e.windowType && (this.windowType = e.windowType); 46 void 0 !== e.hideEventId && (this.hideEventId = e.hideEventId); 47 void 0 !== e.showControl && (this.showControl = e.showControl); 48 void 0 !== e.xComponentController && (this.xComponentController = e.xComponentController); 49 void 0 !== e.surfaceId && (this.surfaceId = e.surfaceId); 50 void 0 !== e.controlTransEffect && (this.controlTransEffect = e.controlTransEffect); 51 void 0 !== e.hideControlNow && (this.hideControlNow = e.hideControlNow); 52 void 0 !== e.hideControlDelay && (this.hideControlDelay = e.hideControlDelay) 53 } 54 55 updateStateVars(e) { 56 } 57 58 purgeVariableDependenciesOnElmtId(e) { 59 this.__showControl.purgeDependencyOnElmtId(e); 60 this.__hideControlNow.purgeDependencyOnElmtId(e); 61 this.__hideControlDelay.purgeDependencyOnElmtId(e) 62 } 63 64 aboutToBeDeleted() { 65 this.__showControl.aboutToBeDeleted(); 66 this.__hideControlNow.aboutToBeDeleted(); 67 this.__hideControlDelay.aboutToBeDeleted(); 68 SubscriberManager.Get().delete(this.id__()); 69 this.aboutToBeDeletedInternal() 70 } 71 72 get showControl() { 73 return this.__showControl.get() 74 } 75 76 set showControl(e) { 77 this.__showControl.set(e) 78 } 79 80 get hideControlNow() { 81 return this.__hideControlNow.get() 82 } 83 84 set hideControlNow(e) { 85 this.__hideControlNow.set(e) 86 } 87 88 get hideControlDelay() { 89 return this.__hideControlDelay.get() 90 } 91 92 set hideControlDelay(e) { 93 this.__hideControlDelay.set(e) 94 } 95 96 onHideControlNow() { 97 this.hideControlNow && this.switchToHideWithoutAnime(); 98 this.hideControlNow = !1 99 } 100 101 onHideControlDelay() { 102 this.hideControlDelay && this.delayHide(); 103 this.hideControlDelay = !1 104 } 105 106 switchToShow() { 107 Context.animateTo({ curve: curves.responsiveSpringMotion(0.25, 1) }, (() => { 108 this.showControl = !0 109 })); 110 this.delayHide() 111 } 112 113 switchToHide() { 114 -1 !== this.hideEventId && clearTimeout(this.hideEventId); 115 Context.animateTo({ curve: curves.responsiveSpringMotion(0.25, 1) }, (() => { 116 this.showControl = !1 117 })) 118 } 119 120 switchToHideWithoutAnime() { 121 -1 !== this.hideEventId && clearTimeout(this.hideEventId); 122 this.showControl = !1 123 } 124 125 delayHide() { 126 -1 !== this.hideEventId && clearTimeout(this.hideEventId); 127 this.hideEventId = this.showControl ? setTimeout((() => { 128 Context.animateTo({ curve: curves.responsiveSpringMotion(0.25, 1) }, (() => { 129 this.showControl = !1 130 })) 131 }), 3e3) : -1 132 } 133 134 initialRender() { 135 this.observeComponentCreation2(((e, t) => { 136 Stack.create(); 137 Stack.size({ width: "100%", height: "100%" }) 138 }), Stack); 139 this.observeComponentCreation2(((e, t) => { 140 XComponent.create({ 141 id: this.xComponentId, 142 type: "surface", 143 controller: this.xComponentController 144 }, "pipXComponent"); 145 XComponent.onLoad((() => { 146 pip.initXComponentController(this.xComponentController); 147 console.debug(TAG, "XComponent onLoad done") 148 })); 149 XComponent.size({ width: "100%", height: "100%" }) 150 }), XComponent); 151 this.observeComponentCreation2(((e, t) => { 152 RelativeContainer.create(); 153 RelativeContainer.size({ width: "100%", height: "100%" }); 154 RelativeContainer.id("control"); 155 Gesture.create(GesturePriority.Low); 156 GestureGroup.create(GestureMode.Exclusive); 157 TapGesture.create({ count: 2 }); 158 TapGesture.onAction((e => { 159 this.switchToHideWithoutAnime(); 160 pip.processScale() 161 })); 162 TapGesture.pop(); 163 TapGesture.create({ count: 1 }); 164 TapGesture.onAction((e => { 165 this.showControl ? this.switchToHide() : this.switchToShow() 166 })); 167 TapGesture.pop(); 168 PanGesture.create(); 169 PanGesture.onActionStart((e => { 170 this.switchToHide(); 171 pip.startMove() 172 })); 173 PanGesture.pop(); 174 GestureGroup.pop(); 175 Gesture.pop() 176 }), RelativeContainer); 177 this.observeComponentCreation2(((e, t) => { 178 Stack.create(); 179 Stack.size({ width: "100%", height: "100%" }); 180 Stack.id("fill_stack") 181 }), Stack); 182 Stack.pop(); 183 this.observeComponentCreation2(((e, t) => { 184 If.create(); 185 this.showControl ? this.ifElseBranchUpdateFunction(0, (() => { 186 if (!If.canRetake("control_inner")) { 187 this.observeComponentCreation2(((e, t) => { 188 RelativeContainer.create(); 189 RelativeContainer.size({ width: "100%", height: "100%" }); 190 RelativeContainer.transition(this.controlTransEffect); 191 RelativeContainer.alignRules({ 192 top: { anchor: "__container__", align: VerticalAlign.Top }, 193 right: { anchor: "__container__", align: HorizontalAlign.End } 194 }); 195 RelativeContainer.id("control_inner") 196 }), RelativeContainer); 197 this.observeComponentCreation2(((e, t) => { 198 if (t) { 199 let t = () => ({}); 200 ViewPU.create(new DefaultControl(this, {}, void 0, e, t)) 201 } else this.updateStateVarsOfChildByElmtId(e, {}) 202 }), null); 203 this.observeComponentCreation2(((e, t) => { 204 if (t) { 205 let t = () => ({}); 206 ViewPU.create(new VideoControl(this, {}, void 0, e, t)) 207 } else this.updateStateVarsOfChildByElmtId(e, {}) 208 }), null); 209 RelativeContainer.pop() 210 } 211 })) : this.ifElseBranchUpdateFunction(1, (() => { 212 })) 213 }), If); 214 If.pop(); 215 RelativeContainer.pop(); 216 Stack.pop() 217 } 218 219 rerender() { 220 this.updateDirtyElements() 221 } 222} 223 224class DefaultControl extends ViewPU { 225 constructor(e, t, o, i = -1, n = void 0) { 226 super(e, o, i); 227 "function" == typeof n && (this.paramsGenerator_ = n); 228 this.__hideControlNow = this.initializeConsume("hideControlNow", "hideControlNow"); 229 this.setInitiallyProvidedValue(t) 230 } 231 232 setInitiallyProvidedValue(e) { 233 } 234 235 updateStateVars(e) { 236 } 237 238 purgeVariableDependenciesOnElmtId(e) { 239 this.__hideControlNow.purgeDependencyOnElmtId(e) 240 } 241 242 aboutToBeDeleted() { 243 this.__hideControlNow.aboutToBeDeleted(); 244 SubscriberManager.Get().delete(this.id__()); 245 this.aboutToBeDeletedInternal() 246 } 247 248 get hideControlNow() { 249 return this.__hideControlNow.get() 250 } 251 252 set hideControlNow(e) { 253 this.__hideControlNow.set(e) 254 } 255 256 initialRender() { 257 this.observeComponentCreation2(((e, t) => { 258 RelativeContainer.create(); 259 RelativeContainer.width("100%"); 260 RelativeContainer.height(48); 261 RelativeContainer.linearGradient({ angle: 180, colors: [["#30000000", 0], ["#00000000", 1]] }); 262 RelativeContainer.alignRules({ 263 top: { anchor: "__container__", align: VerticalAlign.Top }, 264 left: { anchor: "__container__", align: HorizontalAlign.Start } 265 }); 266 RelativeContainer.id("default_control") 267 }), RelativeContainer); 268 this.observeComponentCreation2(((e, t) => { 269 Button.createWithChild({ type: ButtonType.Circle }); 270 Button.backgroundColor("#00FFFFFF"); 271 Button.size({ width: 24, height: 24 }); 272 Button.margin(12); 273 Button.alignRules({ 274 center: { anchor: "__container__", align: VerticalAlign.Center }, 275 left: { anchor: "__container__", align: HorizontalAlign.Start } 276 }); 277 Button.id("control_exit"); 278 Button.responseRegion({ x: "-50%", y: "-50%", width: "200%", height: "200%" }); 279 Button.onClick((() => { 280 this.hideControlNow = !0; 281 pip.close(); 282 console.debug(TAG, "action: exit") 283 })) 284 }), Button); 285 this.observeComponentCreation2(((e, t) => { 286 Image.create({ 287 id: -1, 288 type: 2e4, 289 params: ["sys.media.ohos_ic_public_close"], 290 bundleName: "", 291 moduleName: "" 292 }); 293 Image.size({ width: 24, height: 24 }); 294 Image.fillColor({ 295 id: -1, 296 type: 10001, 297 params: ["sys.color.ohos_id_color_primary_contrary"], 298 bundleName: "", 299 moduleName: "" 300 }); 301 Image.objectFit(ImageFit.Contain) 302 }), Image); 303 Button.pop(); 304 this.observeComponentCreation2(((e, t) => { 305 Button.createWithChild({ type: ButtonType.Circle }); 306 Button.backgroundColor("#00FFFFFF"); 307 Button.size({ width: 24, height: 24 }); 308 Button.margin(12); 309 Button.alignRules({ 310 center: { anchor: "__container__", align: VerticalAlign.Center }, 311 right: { anchor: "__container__", align: HorizontalAlign.End } 312 }); 313 Button.id("control_restore"); 314 Button.responseRegion({ x: "-50%", y: "-50%", width: "200%", height: "200%" }); 315 Button.onClick((() => { 316 this.hideControlNow = !0; 317 pip.restore(); 318 console.debug(TAG, "action: restore") 319 })) 320 }), Button); 321 this.observeComponentCreation2(((e, t) => { 322 Image.create({ 323 id: -1, 324 type: 2e4, 325 params: ["sys.media.ohos_ic_public_restore"], 326 bundleName: "", 327 moduleName: "" 328 }); 329 Image.fillColor({ 330 id: -1, 331 type: 10001, 332 params: ["sys.color.ohos_id_color_primary_contrary"], 333 bundleName: "", 334 moduleName: "" 335 }); 336 Image.objectFit(ImageFit.Contain) 337 }), Image); 338 Button.pop(); 339 RelativeContainer.pop() 340 } 341 342 rerender() { 343 this.updateDirtyElements() 344 } 345} 346 347class VideoControl extends ViewPU { 348 constructor(e, t, o, i = -1, n = void 0) { 349 super(e, o, i); 350 "function" == typeof n && (this.paramsGenerator_ = n); 351 this.__isPlaying = new ObservedPropertySimplePU(!0, this, "isPlaying"); 352 this.__shouldShowNextAndPrev = new ObservedPropertySimplePU(!0, this, "shouldShowNextAndPrev"); 353 this.__horMargin = new ObservedPropertySimplePU(12, this, "horMargin"); 354 this.__hideControlDelay = this.initializeConsume("hideControlDelay", "hideControlDelay"); 355 this.setInitiallyProvidedValue(t) 356 } 357 358 setInitiallyProvidedValue(e) { 359 void 0 !== e.isPlaying && (this.isPlaying = e.isPlaying); 360 void 0 !== e.shouldShowNextAndPrev && (this.shouldShowNextAndPrev = e.shouldShowNextAndPrev); 361 void 0 !== e.horMargin && (this.horMargin = e.horMargin) 362 } 363 364 updateStateVars(e) { 365 } 366 367 purgeVariableDependenciesOnElmtId(e) { 368 this.__isPlaying.purgeDependencyOnElmtId(e); 369 this.__shouldShowNextAndPrev.purgeDependencyOnElmtId(e); 370 this.__horMargin.purgeDependencyOnElmtId(e); 371 this.__hideControlDelay.purgeDependencyOnElmtId(e) 372 } 373 374 aboutToBeDeleted() { 375 this.__isPlaying.aboutToBeDeleted(); 376 this.__shouldShowNextAndPrev.aboutToBeDeleted(); 377 this.__horMargin.aboutToBeDeleted(); 378 this.__hideControlDelay.aboutToBeDeleted(); 379 SubscriberManager.Get().delete(this.id__()); 380 this.aboutToBeDeletedInternal() 381 } 382 383 get isPlaying() { 384 return this.__isPlaying.get() 385 } 386 387 set isPlaying(e) { 388 this.__isPlaying.set(e) 389 } 390 391 get shouldShowNextAndPrev() { 392 return this.__shouldShowNextAndPrev.get() 393 } 394 395 set shouldShowNextAndPrev(e) { 396 this.__shouldShowNextAndPrev.set(e) 397 } 398 399 get horMargin() { 400 return this.__horMargin.get() 401 } 402 403 set horMargin(e) { 404 this.__horMargin.set(e) 405 } 406 407 get hideControlDelay() { 408 return this.__hideControlDelay.get() 409 } 410 411 set hideControlDelay(e) { 412 this.__hideControlDelay.set(e) 413 } 414 415 initialRender() { 416 this.observeComponentCreation2(((e, t) => { 417 RelativeContainer.create(); 418 RelativeContainer.width("100%"); 419 RelativeContainer.height(48); 420 RelativeContainer.linearGradient({ angle: 0, colors: [["#30000000", 0], ["#00000000", 1]] }); 421 RelativeContainer.onAreaChange(((e, t) => { 422 if (t.width < 104) this.shouldShowNextAndPrev = !1; else if (t.width < 152) { 423 this.horMargin = (t.width - 104) / 4; 424 this.shouldShowNextAndPrev = !0 425 } else { 426 this.horMargin = 12; 427 this.shouldShowNextAndPrev = !0 428 } 429 })); 430 RelativeContainer.alignRules({ 431 bottom: { anchor: "__container__", align: VerticalAlign.Bottom }, 432 left: { anchor: "__container__", align: HorizontalAlign.Start } 433 }); 434 RelativeContainer.id("video_control") 435 }), RelativeContainer); 436 this.observeComponentCreation2(((e, t) => { 437 Button.createWithChild({ type: ButtonType.Circle }); 438 Button.backgroundColor("#00FFFFFF"); 439 Button.size({ width: 24, height: 24 }); 440 Button.margin({ top: 12, bottom: 12 }); 441 Button.alignRules({ 442 center: { anchor: "__container__", align: VerticalAlign.Center }, 443 middle: { anchor: "__container__", align: HorizontalAlign.Center } 444 }); 445 Button.id("control_play"); 446 Button.responseRegion({ x: "-50%", y: "-50%", width: "200%", height: "200%" }); 447 Button.onClick((() => { 448 this.isPlaying = !this.isPlaying; 449 this.hideControlDelay = !0; 450 pip.triggerAction("playbackStateChanged"); 451 console.debug(TAG, "action: play or pause") 452 })) 453 }), Button); 454 this.observeComponentCreation2(((e, t) => { 455 Image.create(this.isPlaying ? { 456 id: -1, 457 type: 2e4, 458 params: ["sys.media.ohos_ic_public_pause"], 459 bundleName: "", 460 moduleName: "" 461 } : { 462 id: -1, 463 type: 2e4, 464 params: ["sys.media.ohos_ic_public_play"], 465 bundleName: "", 466 moduleName: "" 467 }); 468 Image.fillColor({ 469 id: -1, 470 type: 10001, 471 params: ["sys.color.ohos_id_color_primary_contrary"], 472 bundleName: "", 473 moduleName: "" 474 }); 475 Image.objectFit(ImageFit.Contain) 476 }), Image); 477 Button.pop(); 478 this.observeComponentCreation2(((e, t) => { 479 Button.createWithChild({ type: ButtonType.Circle }); 480 Button.backgroundColor("#00FFFFFF"); 481 Button.size({ width: 24, height: 24 }); 482 Button.margin({ left: this.horMargin, right: this.horMargin * 2, top: 12, bottom: 12 }); 483 Button.visibility(this.shouldShowNextAndPrev ? Visibility.Visible : Visibility.None); 484 Button.alignRules({ 485 center: { anchor: "__container__", align: VerticalAlign.Center }, 486 right: { anchor: "control_play", align: HorizontalAlign.Start } 487 }); 488 Button.id("control_play_last"); 489 Button.responseRegion({ x: "-50%", y: "-50%", width: "200%", height: "200%" }); 490 Button.onClick((() => { 491 this.hideControlDelay = !0; 492 pip.triggerAction("previousVideo"); 493 console.debug(TAG, "action: play last") 494 })) 495 }), Button); 496 this.observeComponentCreation2(((e, t) => { 497 Image.create({ 498 id: -1, 499 type: 2e4, 500 params: ["sys.media.ohos_ic_public_play_last"], 501 bundleName: "", 502 moduleName: "" 503 }); 504 Image.fillColor({ 505 id: -1, 506 type: 10001, 507 params: ["sys.color.ohos_id_color_primary_contrary"], 508 bundleName: "", 509 moduleName: "" 510 }); 511 Image.objectFit(ImageFit.Contain) 512 }), Image); 513 Button.pop(); 514 this.observeComponentCreation2(((e, t) => { 515 Button.createWithChild({ type: ButtonType.Circle }); 516 Button.backgroundColor("#00FFFFFF"); 517 Button.size({ width: 24, height: 24 }); 518 Button.margin({ left: this.horMargin * 2, right: this.horMargin, top: 12, bottom: 12 }); 519 Button.visibility(this.shouldShowNextAndPrev ? Visibility.Visible : Visibility.None); 520 Button.alignRules({ 521 center: { anchor: "__container__", align: VerticalAlign.Center }, 522 left: { anchor: "control_play", align: HorizontalAlign.End } 523 }); 524 Button.id("control_play_next"); 525 Button.responseRegion({ x: "-50%", y: "-50%", width: "200%", height: "200%" }); 526 Button.onClick((() => { 527 this.hideControlDelay = !0; 528 pip.triggerAction("nextVideo"); 529 console.debug(TAG, "action: play next") 530 })) 531 }), Button); 532 this.observeComponentCreation2(((e, t) => { 533 Image.create({ 534 id: -1, 535 type: 2e4, 536 params: ["sys.media.ohos_ic_public_play_next"], 537 bundleName: "", 538 moduleName: "" 539 }); 540 Image.fillColor({ 541 id: -1, 542 type: 10001, 543 params: ["sys.color.ohos_id_color_primary_contrary"], 544 bundleName: "", 545 moduleName: "" 546 }); 547 Image.objectFit(ImageFit.Contain) 548 }), Image); 549 Button.pop(); 550 RelativeContainer.pop() 551 } 552 553 rerender() { 554 this.updateDirtyElements() 555 } 556} 557 558ViewStackProcessor.StartGetAccessRecordingFor(ViewStackProcessor.AllocateNewElmetIdForNextComponent()); 559loadDocument(new PiPVideo(void 0, {})); 560ViewStackProcessor.StopGetAccessRecording();