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