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