1/* 2 * Copyright (c) 2023-2024 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 { 23 PersistType, 24 PreferencesService 25} from '@ohos/common/src/main/ets/default/featurecommon/preferences/PreferencesService'; 26 27class StateStruct { 28 isThirdPartyCall: boolean = false; 29 thirdCallAction: string = ''; 30 isFaCall: boolean = false; 31 action: string = ''; 32 uiEnable: boolean = true; 33 modeIndex: number = 0; 34 mode: string = 'PHOTO'; 35 isShowMoreList: boolean = false; 36} 37 38class ControlDispatcher { 39 private mDispatch: Dispatch = (data) => data; 40 41 public setDispatch(dispatch: Dispatch) { 42 this.mDispatch = dispatch; 43 } 44 45 public changeToMode(mode: string): void { 46 this.mDispatch(Action.uiState(false)); 47 this.mDispatch(Action.changeMode(mode)); 48 this.mDispatch(Action.updateShowBigTextFlag(true)); 49 } 50 51 public updateModeIndex(index: number): void { 52 this.mDispatch(Action.updateModeIndex(index)); 53 } 54 55 public updateShowMoreList(isShowMoreList: boolean): void { 56 this.mDispatch(Action.updateShowMoreList(isShowMoreList)); 57 } 58 59 public initAction(action: string): void { 60 this.mDispatch(Action.initAction(action)); 61 } 62 63 public initMode(mode: string): void { 64 this.mDispatch(Action.initMode(mode)); 65 } 66 67 public updateListStatus(enable: boolean): void { 68 this.mDispatch(Action.uiState(enable)); 69 } 70} 71 72class SwipeModeIndexStruct { 73 swipeModeIndex: number = 0; 74} 75 76 77@Component 78export struct Control { 79 private TAG: string = '[Control]'; 80 appEventBus: EventBus = EventBusManager.getInstance().getEventBus(); 81 private scroller: Scroller = new Scroller(); 82 private modeArray: Array<string> = ['PHOTO', 'VIDEO']; 83 private itemWidth: number = 56; 84 protected mPreferencesService: PreferencesService = PreferencesService.getInstance(); 85 @State state: StateStruct = new StateStruct(); 86 private mAction: ControlDispatcher = new ControlDispatcher(); 87 @State startScroll: number = 0; 88 @State endScroll: number = 0; 89 @State index: number = 0; 90 91 aboutToAppear(): void { 92 Log.info(`${this.TAG} aboutToAppear E`); 93 getStore().subscribe((state: OhCombinedState) => { 94 this.state = { 95 isThirdPartyCall: state.contextReducer.isThirdPartyCall, 96 thirdCallAction: state.contextReducer.thirdCallAction, 97 isFaCall: state.contextReducer.isFaCall, 98 action: state.contextReducer.action, 99 uiEnable: state.contextReducer.uiEnable, 100 modeIndex: state.modeReducer.modeIndex, 101 mode: state.modeReducer.mode, 102 isShowMoreList: state.modeReducer.isShowMoreList 103 }; 104 }, (dispatch: Dispatch) => { 105 this.mAction.setDispatch(dispatch); 106 }); 107 108 this.appEventBus.on(Action.ACTION_SWIPE_MODE, (data: SwipeModeIndexStruct) => this.swipeChangeMode(data)); 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_SWIPE_MODE, (data: SwipeModeIndexStruct) => this.swipeChangeMode(data)); 115 Log.info(`${this.TAG} aboutToDisappear X`); 116 } 117 118 private changeToMode(modeIndex: number): void { 119 Log.info(`${this.TAG} changeToMode modeIndex: ${modeIndex} E`); 120 this.scroller.scrollToIndex(modeIndex); 121 if (this.modeArray[modeIndex] !== this.state.mode) { 122 Log.info(`${this.TAG} this.state.changeToMode(${this.modeArray[modeIndex]})`); 123 this.mAction.changeToMode(this.modeArray[modeIndex]); 124 this.mPreferencesService.putModeValue(PersistType.FOR_AWHILE, modeIndex); 125 this.mPreferencesService.flushMode(); 126 } else { 127 this.mAction.updateListStatus(true); 128 } 129 Log.info(`${this.TAG} changeToMode X`); 130 } 131 132 private getModeFontWeight(modeIndex: number): FontWeight { 133 if (this.state.mode === this.modeArray[modeIndex]) { 134 return FontWeight.Bold; 135 } else { 136 return FontWeight.Regular; 137 } 138 } 139 140 private swipeChangeMode(data: SwipeModeIndexStruct): void { 141 this.changeToMode(data.swipeModeIndex); 142 } 143 144 build() { 145 Column() { 146 Stack({ alignContent: Alignment.BottomStart }) { 147 if ((this.state.isThirdPartyCall || this.state.isFaCall) && this.state.mode === 'PHOTO' && (this.state.thirdCallAction != 'ALL')) { 148 Row() { 149 Text($r('app.string.photo_mode')) 150 .width('100%') 151 .height('100%') 152 .fontSize(14) 153 .fontColor(Color.White) 154 .fontWeight(FontWeight.Bold) 155 .textAlign(TextAlign.Center) 156 }.width('100%').height('100%').offset({ x: -156, y: 0 }) 157 } else if ((this.state.isThirdPartyCall || this.state.isFaCall) && this.state.mode === 'VIDEO' && (this.state.thirdCallAction != 'ALL')) { 158 Row() { 159 Text($r('app.string.video_mode')) 160 .width('100%') 161 .height('100%') 162 .fontSize(14) 163 .fontColor(Color.White) 164 .fontWeight(FontWeight.Bold) 165 .textAlign(TextAlign.Center) 166 }.width('100%').height('100%').offset({ x: -156, y: 0 }) 167 } else { 168 List({ initialIndex: this.state.modeIndex, scroller: this.scroller }) { 169 ListItem() { 170 }.width(56).height('100%') 171 172 ListItem() { 173 Text($r('app.string.photo_mode')) 174 .width('100%') 175 .height('100%') 176 .fontColor('#fff') 177 .fontSize($r('sys.float.ohos_id_text_size_sub_title3')) 178 .fontWeight(this.getModeFontWeight(0)) 179 .textAlign(TextAlign.Center) 180 .enabled(this.state.uiEnable) 181 .onClick(() => { 182 this.changeToMode(0) 183 }) 184 }.width(56).height('100%') 185 186 ListItem() { 187 Text($r('app.string.video_mode')) 188 .width('100%') 189 .height('100%') 190 .fontColor('#fff') 191 .fontSize($r('sys.float.ohos_id_text_size_sub_title3')) 192 .fontWeight(this.getModeFontWeight(1)) 193 .textAlign(TextAlign.Center) 194 .enabled(this.state.uiEnable) 195 .onClick(() => { 196 this.changeToMode(1) 197 }) 198 }.width(56).height('100%') 199 200 ListItem() { 201 }.width(56).height('100%') 202 } 203 .width(this.itemWidth * 3) 204 .height('100%') 205 .scrollBar(BarState.Off) 206 .listDirection(Axis.Horizontal) 207 .edgeEffect(EdgeEffect.None) 208 .chainAnimation(false) 209 .enabled(this.state.uiEnable) 210 .onScrollIndex((firstIndex: number, lastIndex: number, centerIndex: number) => { 211 Log.info(`${this.TAG} Control scroll index first: ${firstIndex}, centerIndex: ${centerIndex}, last: ${lastIndex}`) 212 this.index = firstIndex; 213 this.mAction.updateModeIndex(firstIndex); 214 Log.info(`${this.TAG} onScrollIndex this.state.modeIndex: ${this.state.modeIndex}`) 215 }) 216 .onScrollStop(() => { 217 Log.info(`${this.TAG} onScrollStop`); 218 this.changeToMode(this.index); 219 }) 220 } 221 Column() { 222 Column() { 223 }.width(6).height(6).borderRadius(3).backgroundColor('#007DFF') 224 }.width('100%').height(18).offset({ x: -156, y: 0 }) 225 }.width('100%').height(58) 226 } 227 } 228}