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 16import { Action } from '@ohos/common/src/main/ets/default/redux/actions/Action' 17import { EventBus } from '@ohos/common/src/main/ets/default/worker/eventbus/EventBus' 18import { EventBusManager } from '@ohos/common/src/main/ets/default/worker/eventbus/EventBusManager' 19import { Log } from '@ohos/common/src/main/ets/default/utils/Log' 20import { OhCombinedState } from '@ohos/common/src/main/ets/default/redux/store' 21import { getStore } from '@ohos/common/src/main/ets/default/redux/store' 22import { Dispatch } from '@ohos/common/src/main/ets/default/redux/core/redux/types/store' 23import { GlobalContext } from '@ohos/common/src/main/ets/default/utils/GlobalContext' 24 25class StateStruct { 26 recordingTime: number = 0; 27 recordingTimeDisplay: string = ''; 28 isRecordingPaused: boolean = false; 29 isRecordingSpotVisible: boolean = true; 30 isThirdPartyCall: boolean = false; 31} 32 33class BigVideoTimerDispatcher { 34 private mDispatch: Dispatch = (data) => data; 35 36 public setDispatch(dispatch: Dispatch) { 37 this.mDispatch = dispatch; 38 } 39 40 public updateRecordingTime(recordingTime: number): void { 41 this.mDispatch(Action.updateRecordingTime(recordingTime)); 42 } 43 44 public updateSmallVideoTimerVisible(visible: boolean): void { 45 this.mDispatch(Action.updateSmallVideoTimerVisible(visible)); 46 } 47 48 public updateBigVideoTimerVisible(visible: boolean): void { 49 this.mDispatch(Action.updateBigVideoTimerVisible(visible)); 50 } 51 52 public updateRecordingSpotVisible(visible: boolean): void { 53 this.mDispatch(Action.updateRecordingSpotVisible(visible)); 54 } 55 56 public updateRecordingTimeDisplay(timeDisplay: string): void { 57 this.mDispatch(Action.updateRecordingTimeDisplay(timeDisplay)); 58 } 59 60 public stopRecording(): void { 61 this.mDispatch(Action.stopRecording()) 62 this.mDispatch(Action.updateVideoState('beforeTakeVideo')) 63 this.mDispatch(Action.updateBigVideoTimerVisible(false)) 64 this.mDispatch(Action.updateSmallVideoTimerVisible(false)) 65 this.mDispatch(Action.updateScreenStatus(false)) 66 } 67} 68 69@Component 70export struct BigVideoTimer { 71 private TAG: string = '[BigVideoTimer]' 72 private timer: number = 0 73 private timerTick: number = 0 74 private appEventBus: EventBus = EventBusManager.getInstance().getEventBus() 75 @State state: StateStruct = new StateStruct() 76 private mAction: BigVideoTimerDispatcher = new BigVideoTimerDispatcher(); 77 78 private async onRecordPausedBig() { 79 Log.info(`${this.TAG} onRecordPaused timer id: ${this.timer} E`) 80 clearInterval(this.timer) 81 Log.info(`${this.TAG} onRecordPaused X`) 82 } 83 84 private async onRecordResumedBig() { 85 Log.info(`${this.TAG} onRecordResumed E`) 86 if (this.state.recordingTime <= 2) { 87 this.setIntervalTimer() 88 } 89 Log.info(`${this.TAG} onRecordResumed X`) 90 } 91 92 aboutToAppear(): void { 93 Log.info(`${this.TAG} aboutToAppear E`) 94 getStore().subscribe((state: OhCombinedState) => { 95 this.state = { 96 recordingTime: state.RecordReducer.recordingTime, 97 recordingTimeDisplay: state.RecordReducer.recordingTimeDisplay, 98 isRecordingPaused: state.RecordReducer.isRecordingPaused, 99 isRecordingSpotVisible: state.RecordReducer.isRecordingSpotVisible, 100 isThirdPartyCall: state.ContextReducer.isThirdPartyCall, 101 }; 102 }, (dispatch: Dispatch) => { 103 this.mAction.setDispatch(dispatch); 104 }); 105 106 this.setIntervalTimer() 107 this.appEventBus.on(Action.ACTION_RECORD_PAUSE, () => this.onRecordPausedBig()) 108 this.appEventBus.on(Action.ACTION_RECORD_RESUME, () => this.onRecordResumedBig()) 109 Log.info(`${this.TAG} aboutToAppear X`) 110 } 111 112 aboutToDisappear(): void { 113 Log.info(`${this.TAG} aboutToDisappear E`) 114 this.appEventBus.off(Action.ACTION_RECORD_PAUSE, () => this.onRecordPausedBig()) 115 this.appEventBus.off(Action.ACTION_RECORD_RESUME, () => this.onRecordResumedBig()) 116 Log.info(`${this.TAG} clearInterval timer id: ${this.timer}`) 117 clearInterval(this.timer) 118 Log.info(`${this.TAG} aboutToDisappear X`) 119 } 120 121 private setIntervalTimer(): void { 122 clearInterval(this.timer) 123 this.timer = setInterval(() => { 124 this.timerTick++ 125 if (this.timerTick % 2 === 0) { 126 this.mAction.updateRecordingTime(this.state.recordingTime + 1) 127 let shownSec = '00' 128 let shownMin = '00' 129 let sec = this.state.recordingTime % 60 130 if (sec < 10) { 131 shownSec = `0${sec}` 132 } else { 133 shownSec = `${sec}` 134 } 135 let minute = Math.floor(this.state.recordingTime / 60) 136 if (minute < 10) { 137 shownMin = `0${minute}` 138 } else { 139 shownMin = `${minute}` 140 } 141 this.mAction.updateRecordingTimeDisplay(`${shownMin}:${shownSec}`) 142 if (this.state.recordingTime > 2) { 143 clearInterval(this.timer) 144 this.mAction.updateSmallVideoTimerVisible(true) 145 this.mAction.updateBigVideoTimerVisible(false) 146 } 147 } 148 this.mAction.updateRecordingSpotVisible(!this.state.isRecordingSpotVisible) 149 if (this.state.isThirdPartyCall && GlobalContext.get().getCameraAbilityWant().parameters?.durationLimit) { 150 try { 151 let durationLimit: number = Number.parseInt(GlobalContext.get().getCameraAbilityWant().parameters?.durationLimit as string) 152 Log.info(`${this.TAG} durationLimit is ${durationLimit}`); 153 if (this.state.recordingTime >= durationLimit) { 154 this.mAction.stopRecording(); 155 } 156 } catch (error) { 157 Log.info(`${this.TAG} picker durationLimit --> ${JSON.stringify(error)}}`) 158 } 159 } 160 }, 500) 161 } 162 163 build() { 164 Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 165 Text('').layoutWeight(1) 166 if (this.state.isRecordingPaused) { 167 Image($r('app.media.ic_video_recording')).width(12).height(12).fillColor(Color.White) 168 } else { 169 if (this.state.isRecordingSpotVisible) { 170 Column() { 171 } 172 .width(12) 173 .height(12) 174 .backgroundColor('#FF0000') 175 .borderRadius(6) 176 .visibility(Visibility.Visible) 177 } else { 178 Column() { 179 } 180 .width(12) 181 .height(12) 182 .backgroundColor('#FF0000') 183 .borderRadius(6) 184 .visibility(Visibility.Hidden) 185 } 186 } 187 Text(`${this.state.recordingTimeDisplay}`) 188 .margin({ left: 8, right: 8 }) 189 .fontSize('50fp') 190 .fontWeight(300) 191 .fontColor('#FFFFFF') 192 .textAlign(TextAlign.Center) 193 Text('').width(12).height(12) 194 Text('').layoutWeight(1) 195 }.width('100%').height(96) 196 } 197}