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 '../../redux/actions/Action';
17import { CameraSwitchController } from './CameraSwitchController';
18import { Dispatch, OhCombinedState } from '../../redux/store';
19import { getStore } from '../../redux/store';
20import { Log } from '../../utils/Log';
21import MultiCameraDialog from '../customdialog/MultiCameraDialog';
22import deviceInfo from '@ohos.deviceInfo';
23import { GlobalContext } from '../../utils/GlobalContext';
24import { CameraId } from '../../setting/settingitem/CameraId';
25
26let storageCameraId: string = AppStorage.Link('storageCameraId') as string;
27
28class StateStruct {
29  mode: string = 'PHOTO';
30  uiEnable: boolean = true;
31  cameraPosition: CameraId = CameraId.BACK;
32  videoState: string = 'beforeTakeVideo';
33}
34
35
36class CameraSwitchDispatcher {
37  private mDispatch: Dispatch = (data) => data;
38
39  public setDispatch(dispatch: Dispatch) {
40    this.mDispatch = dispatch;
41  }
42
43  public changeCameraPosition(cameraPosition: string): void {
44    this.mDispatch(Action.uiState(false));
45    this.mDispatch(Action.switchCamera(cameraPosition));
46    this.mDispatch(Action.resetZoomRatio(1));
47  }
48}
49
50
51@Component
52export struct CameraSwitchButton {
53  private TAG: string = '[CameraSwitchButton]:'
54  @State state: StateStruct = new StateStruct()
55  @State deviceType: string = deviceInfo.deviceType
56  @StorageLink('storageCameraId') storageCameraId: string = ''
57  icon: Resource = $r('app.media.small_switch_camera')
58  mWidth: number = 0;
59  mHeight: number = 0;
60  mMargin: number = 0;
61  type: ButtonType = ButtonType.Capsule;
62  stateEffect: boolean = false;
63  private mAction: CameraSwitchDispatcher = new CameraSwitchDispatcher();
64  cameraSwitchController: CameraSwitchController = new CameraSwitchController()
65  multiDialogController: CustomDialogController = new CustomDialogController({
66    builder: MultiCameraDialog({
67      cancel: () => this.existView(),
68      deviceType: $deviceType
69    }),
70    autoCancel: true,
71    alignment: DialogAlignment.Center,
72    customStyle: true,
73    cancel: this.existView
74  })
75
76  aboutToAppear() {
77    Log.info(`${this.TAG} aboutToAppear E`);
78    getStore().subscribe((state: OhCombinedState) => {
79      this.state = {
80        mode: state.modeReducer.mode,
81        uiEnable: state.contextReducer.uiEnable,
82        cameraPosition: state.cameraReducer.cameraPosition,
83        videoState: state.recordReducer.videoState
84      };
85    }, (dispatch: Dispatch) => {
86      this.mAction.setDispatch(dispatch);
87    });
88    this.cameraSwitchController.getParam()
89    this.icon = this.cameraSwitchController.icon
90    this.mWidth = this.cameraSwitchController.width
91    this.mHeight = this.cameraSwitchController.height
92    this.mMargin = this.cameraSwitchController.margin
93    this.type = this.cameraSwitchController.type
94    this.stateEffect = this.cameraSwitchController.stateEffect
95    Log.info(`${this.TAG} aboutToAppear X`)
96  }
97
98  private openMultiDialog() {
99    Log.info(`${this.TAG} openMultiDialog E`)
100    this.multiDialogController.open()
101    Log.info(`${this.TAG} openMultiDialog X`)
102  }
103
104  private existView(): void {}
105
106  build() {
107    Column() {
108      Stack() {
109        Image($r('app.media.small_switch_camera'))
110          .width('67.5%').aspectRatio(1)
111          .clip(new Circle({ width: '100%', height: '100%' }))
112        Column() {}.width(44).height(44)
113        .border({ width: 1, color: Color.White, radius: 22, style: BorderStyle.Solid })
114      }
115      .width('100%').height('100%').enabled(this.state.uiEnable)
116      .onClick(() => {
117        Log.info(`${this.TAG} onClick invoke E`)
118        Log.info(`${this.TAG} this.state.videoState: ${this.state.videoState}, this.state.mode: ${this.state.mode}`)
119        Log.info(`${this.TAG} this.state.cameraPosition: ${this.state.cameraPosition}`)
120        if (this.state.videoState === 'beforeTakeVideo') {
121          if (this.state.mode === 'MULTI') {
122            this.openMultiDialog()
123          } else {
124            GlobalContext.get().setObject('switchCameraTime',new Date().getTime())
125            if (this.state.cameraPosition !== 'BACK') {
126              this.mAction.changeCameraPosition('BACK')
127              this.storageCameraId = 'BACK'
128            } else {
129              this.mAction.changeCameraPosition('FRONT')
130              this.storageCameraId = 'FRONT'
131            }
132          }
133        }
134        Log.info(`${this.TAG} onClick invoke X`)
135      })
136    }.width(44).aspectRatio(1)
137  }
138}