• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 display from '@ohos.display';
17import { Action } from '@ohos/common/src/main/ets/default/redux/actions/Action';
18import { EventBus } from '@ohos/common/src/main/ets/default/worker/eventbus/EventBus';
19import { EventBusManager } from '@ohos/common/src/main/ets/default/worker/eventbus/EventBusManager';
20import { Dispatch, OhCombinedState } from '@ohos/common/src/main/ets/default/redux/store';
21import { getStore } from '@ohos/common/src/main/ets/default/redux/store';
22import { Log } from '@ohos/common/src/main/ets/default/utils/Log';
23import {
24  PersistType,
25  PreferencesService
26} from '@ohos/common/src/main/ets/default/featurecommon/preferences/PreferencesService';
27
28class StateStruct {
29  isThirdPartyCall: boolean = false;
30  isFaCall: boolean = false;
31  action: string = '';
32  uiEnable: boolean = true;
33  modeIndex: number = 1;
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 thirdPartyCall(isThirdPartyCall: boolean, action: string): void {
60    this.mDispatch(Action.thirdPartyCall(isThirdPartyCall, action));
61  }
62
63  public initAction(action: string): void {
64    this.mDispatch(Action.initAction(action));
65  }
66
67  public initMode(mode: string): void {
68    this.mDispatch(Action.initMode(mode));
69  }
70
71  public updateListStatus(enable: boolean): void {
72    this.mDispatch(Action.uiState(enable));
73  }
74}
75
76class SwipeModeIndexStruct {
77  swipeModeIndex: number = 0;
78}
79
80
81@Component
82export struct Control {
83  private TAG: string = '[Control]'
84  appEventBus: EventBus = EventBusManager.getInstance().getEventBus()
85  private scroller: Scroller = new Scroller()
86  private modeArray: Array<string> = ['MULTI', 'PHOTO', 'VIDEO']
87  private isScroll: boolean = false
88  private scrollDistance: number = 0
89  protected mPreferencesService: PreferencesService = PreferencesService.getInstance()
90  @State state: StateStruct = new StateStruct()
91  private mAction: ControlDispatcher = new ControlDispatcher();
92  @State modeBarItemLeftWidth: number = 225
93  @State modeBarItemRightWidth: number = 225
94  @State startScroll: number = 0
95  @State endScroll: number = 0
96  @State index: number = 0
97
98  aboutToAppear(): void {
99    Log.info(`${this.TAG} aboutToAppear E`)
100    getStore().subscribe((state: OhCombinedState) => {
101      this.state = {
102        isThirdPartyCall: state.contextReducer.isThirdPartyCall,
103        isFaCall: state.contextReducer.isFaCall,
104        action: state.contextReducer.action,
105        uiEnable: state.contextReducer.uiEnable,
106        modeIndex: state.modeReducer.modeIndex,
107        mode: state.modeReducer.mode,
108        isShowMoreList: state.modeReducer.isShowMoreList
109      };
110    }, (dispatch: Dispatch) => {
111      this.mAction.setDispatch(dispatch);
112    });
113
114    display.getDefaultDisplay().then((dis) => {
115      this.modeBarItemLeftWidth = px2vp(dis.width) / 2 - 156
116      this.modeBarItemRightWidth = px2vp(dis.width) / 2 - 148
117    })
118    this.appEventBus.on(Action.ACTION_SWIPE_MODE, (data: SwipeModeIndexStruct) => this.swipeChangeMode(data));
119    Log.info(`${this.TAG} aboutToAppear X`)
120  }
121
122  aboutToDisappear(): void {
123    Log.info(`${this.TAG} aboutToDisappear E`)
124    this.appEventBus.off(Action.ACTION_SWIPE_MODE, (data: SwipeModeIndexStruct) => this.swipeChangeMode(data))
125    Log.info(`${this.TAG} aboutToDisappear X`)
126  }
127
128  private changeToMode(modeIndex: number): void {
129    Log.debug(`${this.TAG} changeToMode modeIndex: ${modeIndex} E`)
130    this.scroller.scrollToIndex(modeIndex)
131    if (this.modeArray[modeIndex] !== this.state.mode) {
132      Log.debug(`${this.TAG} this.state.changeToMode(${this.modeArray[modeIndex]})`)
133      this.mAction.changeToMode(this.modeArray[modeIndex])
134      this.mPreferencesService.putModeValue(PersistType.FOR_AWHILE, modeIndex)
135      this.mPreferencesService.flushMode()
136    } else {
137      this.mAction.updateListStatus(true)
138    }
139    Log.debug(`${this.TAG} changeToMode X`)
140  }
141
142  private getModeFontWeight(modeIndex: number): FontWeight {
143    if (this.state.mode === this.modeArray[modeIndex]) {
144      return FontWeight.Bold
145    } else {
146      return FontWeight.Regular
147    }
148  }
149
150  private swipeChangeMode(data: SwipeModeIndexStruct): void {
151    this.changeToMode(data.swipeModeIndex)
152  }
153
154  private scrollSwitchMode(): void {
155    if (this.index == 1 && Math.abs(this.scrollDistance) <= px2vp(28)) {
156      this.changeToMode(1)
157    }
158    if (this.index == 1 && (this.scrollDistance) > px2vp(28)) {
159      this.changeToMode(2)
160    }
161    if (this.index == 1 && (this.scrollDistance) < px2vp(-28)) {
162      this.changeToMode(0)
163    }
164    if (this.index == 0 && (this.scrollDistance < px2vp(36))) {
165      this.changeToMode(0)
166    }
167    if (this.index == 0 && this.scrollDistance <= px2vp(92) && this.scrollDistance >= px2vp(36)) {
168      this.changeToMode(1)
169    }
170    if (this.index == 0 && this.scrollDistance > px2vp(92)) {
171      this.changeToMode(2)
172    }
173    if (this.index == 2 && (this.scrollDistance > px2vp(-28))) {
174      this.changeToMode(2)
175    }
176    if (this.index == 2 && this.scrollDistance <= px2vp(-28) && this.scrollDistance >= px2vp(-92)) {
177      this.changeToMode(1)
178    }
179    if (this.index == 2 && this.scrollDistance < px2vp(-92)) {
180      this.changeToMode(0)
181    }
182  }
183
184  build() {
185    Column() {
186      Stack({ alignContent: Alignment.BottomStart }) {
187        if ((this.state.isThirdPartyCall || this.state.isFaCall) && this.state.mode === 'PHOTO') {
188          Row() {
189            Text($r('app.string.photo_mode'))
190              .width('100%')
191              .height('100%')
192              .fontSize(14)
193              .fontColor(Color.White)
194              .fontWeight(FontWeight.Bold)
195              .textAlign(TextAlign.Center)
196          }.width('100%').height('100%')
197        } else if ((this.state.isThirdPartyCall || this.state.isFaCall) && this.state.mode === 'VIDEO') {
198          Row() {
199            Text($r('app.string.video_mode'))
200              .width('100%')
201              .height('100%')
202              .fontSize(14)
203              .fontColor(Color.White)
204              .fontWeight(FontWeight.Bold)
205              .textAlign(TextAlign.Center)
206          }.width('100%').height('100%')
207        } else {
208          List({ initialIndex: this.state.modeIndex, scroller: this.scroller }) {
209            ListItem() {
210            }.width(64).height('100%')
211
212            ListItem() {
213            }.width(56).height('100%')
214
215            ListItem() {
216            }.width(this.modeBarItemLeftWidth).height('100%')
217
218            ListItem() {
219              Text($r('app.string.multi_mode'))
220                .width('100%')
221                .height('100%')
222                .fontColor('#fff')
223                .fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
224                .fontWeight(this.getModeFontWeight(0))
225                .textAlign(TextAlign.Center)
226                .enabled(this.state.uiEnable)
227                .onClick(() => {
228                  this.changeToMode(0)
229                })
230            }.width(72).height('100%')
231
232            ListItem() {
233              Text($r('app.string.photo_mode'))
234                .width('100%')
235                .height('100%')
236                .fontColor('#fff')
237                .fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
238                .fontWeight(this.getModeFontWeight(1))
239                .textAlign(TextAlign.Center)
240                .enabled(this.state.uiEnable)
241                .onClick(() => {
242                  this.changeToMode(1)
243                })
244            }.width(56).height('100%')
245
246            ListItem() {
247              Text($r('app.string.video_mode'))
248                .width('100%')
249                .height('100%')
250                .fontColor('#fff')
251                .fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
252                .fontWeight(this.getModeFontWeight(2))
253                .textAlign(TextAlign.Center)
254                .enabled(this.state.uiEnable)
255                .onClick(() => {
256                  this.changeToMode(2)
257                })
258            }.width(56).height('100%')
259
260            ListItem() {
261            }.width(this.modeBarItemRightWidth).height('100%')
262
263            ListItem() {
264            }.width(64).height('100%')
265
266            ListItem() {
267            }.width(56).height('100%')
268          }
269          .width('100%')
270          .height('100%')
271          .listDirection(Axis.Horizontal)
272          .edgeEffect(EdgeEffect.None)
273          .chainAnimation(false)
274          .enabled(this.state.uiEnable)
275          .onScrollIndex((firstIndex: number, lastIndex: number) => {
276            Log.debug(`${this.TAG} Control scroll index first: ${firstIndex}, last: ${lastIndex}`)
277            this.mAction.updateModeIndex(firstIndex)
278            Log.debug(`${this.TAG} onScrollIndex this.state.modeIndex: ${this.state.modeIndex}`)
279          })
280          .onScrollStop(() => {
281            Log.info(`${this.TAG} onScrollStop`)
282            this.scrollSwitchMode()
283          })
284          .onScroll((scrollOffset: number, scrollState: ScrollState) => {
285            if (scrollState === ScrollState.Fling) {
286              this.scrollDistance += px2vp(scrollOffset)
287              if (!this.isScroll) {
288                this.isScroll = true
289                this.mAction.updateListStatus(false)
290              }
291            }
292          })
293          .onTouch((event?: TouchEvent) => {
294            if (!event) {
295              return;
296            }
297            if (event.type === TouchType.Down) {
298              this.scrollDistance = 0
299              this.index = this.modeArray.indexOf(this.state.mode)
300              this.startScroll = event.touches[0].screenX
301            }
302            if (event.type === TouchType.Up) {
303              this.endScroll = event.touches[0].screenX
304              this.scrollDistance = px2vp(this.startScroll - this.endScroll)
305              this.isScroll = false
306            }
307          })
308        }
309        Column() {
310          Column() {
311          }.width(6).height(6).borderRadius(3).backgroundColor('#007DFF')
312        }.width('100%').height(18)
313      }.width('100%').height(58)
314    }
315  }
316}