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