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}