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 { CameraService } from '../../camera/CameraService';
17import { CameraId } from '../../setting/settingitem/CameraId';
18import { Log } from '../../utils/Log';
19import EntryComponentForMulti from './EntryComponentForMulti';
20import { Dispatch, OhCombinedState } from '../../redux/store';
21import { getStore } from '../../redux/store';
22import { Action } from '../../redux/actions/Action';
23
24let storageCameraId: string = AppStorage.Link('storageCameraId') as string;
25
26class StateStruct {
27}
28
29class MultiCameraDispatcher {
30  private mDispatch: Dispatch = (data) => data;
31
32  public setDispatch(dispatch: Dispatch) {
33    this.mDispatch = dispatch;
34  }
35
36  public changeCameraPosition(cameraPosition: string): void {
37    this.mDispatch(Action.uiState(false));
38    this.mDispatch(Action.switchCamera(cameraPosition));
39    this.mDispatch(Action.resetZoomRatio(1));
40  }
41}
42
43
44@CustomDialog
45export default struct MultiCameraDialog {
46  private TAG: string = '[MultiCameraDialog]:';
47  private cameraService = CameraService.getInstance();
48  controller?: CustomDialogController;
49  cancel: () => void = () => {};
50  confirm: () => void = () => {};
51  private localList: string[] = [
52  CameraId.FRONT,
53  CameraId.BACK
54  ];
55  @State private moreList: string[] = [];
56  @State state: StateStruct = new StateStruct();
57  @State isShowMore: boolean = false;
58  @State gridColumns: number = 12;
59  @State useSizeTypeOffset: number = 4;
60  @Link deviceType: string;
61  @StorageLink('storageCameraId') storageCameraId: string = '';
62  private mAction: MultiCameraDispatcher = new MultiCameraDispatcher();
63
64  aboutToAppear() {
65    Log.info(`${this.TAG} aboutToAppear.`)
66    getStore().subscribe((state: OhCombinedState) => {
67      this.state = {
68      };
69    }, (dispatch: Dispatch) => {
70      this.mAction.setDispatch(dispatch);
71    });
72
73    let localCameraInfo = this.cameraService.getLocalCameraMap()
74    if (!localCameraInfo.get('front')) {
75      this.localList.shift()
76    } else if (!localCameraInfo.get('back')) {
77      this.localList.pop()
78    }
79    if (this.deviceType === 'phone' || this .deviceType === 'default') {
80      this.gridColumns = 4
81      this.useSizeTypeOffset = 0
82    } else {
83      this.gridColumns = 12
84      this.useSizeTypeOffset = 4
85    }
86  }
87
88  private onChange(item: string): void {
89    Log.info(`${this.TAG} MultiCameraPosition ${JSON.stringify(item)}`)
90    if (item.includes('BACK')) {
91      this.storageCameraId = 'BACK'
92    } else if(item.includes('FRONT')) {
93      this.storageCameraId = 'FRONT'
94    }
95    this.mAction.changeCameraPosition(item);
96    this.cancel();
97    if (this.controller) {
98      this.controller.close();
99    }
100  }
101
102  build() {
103    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
104      GridContainer({ columns: this.gridColumns, gutter: 12, margin: 12 }) {
105        Column() {
106          Row() {
107            Text($r('app.string.select_camera'))
108              .fontSize($r('sys.float.ohos_id_text_size_dialog_tittle'))
109              .fontColor('#E6000000')
110              .opacity(0.9)
111              .fontWeight(FontWeight.Medium)
112              .opacity($r('sys.float.ohos_id_alpha_content_primary'))
113          }
114          .width('100%')
115          .height('56vp')
116
117          Row() {
118            Text($r('app.string.local_device'))
119              .fontSize($r('sys.float.ohos_id_text_size_body2'))
120              .fontColor('#99182431')
121              .fontWeight(FontWeight.Medium)
122          }
123          .width('100%')
124          .height('48vp')
125          .padding({top: 20, bottom: 8})
126
127          List() {
128            ForEach(this.localList, (item: string) => {
129              ListItem() {
130                EntryComponentForMulti({
131                  item: item,
132                  localList: this.localList.toString(),
133                  onChange: (data:string) => this.onChange(data)
134                })
135              }
136              .width('100%')
137              .height(48)
138            })
139          }
140          .listDirection(Axis.Vertical)
141          .divider({ strokeWidth: '1vp', color: '#33182431', startMargin: 0, endMargin: 12})
142
143          Row() {
144            Text($r('app.string.more_devices'))
145              .fontSize($r('sys.float.ohos_id_text_size_body2'))
146              .fontColor('#99182431')
147              .fontWeight(FontWeight.Medium)
148          }
149          .width('100%')
150          .height('48vp')
151          .padding({top: 20, bottom: 8})
152
153          if (this.isShowMore) {
154            List() {
155              ForEach(this.moreList, (item: string) => {
156                ListItem() {
157                  EntryComponentForMulti({
158                    item: item,
159                    localList: this.localList.toString(),
160                    onChange: (data: string) => this.onChange(data)
161                  })
162                }
163                .width('100%')
164                .height(48)
165              })
166            }
167            .listDirection(Axis.Vertical)
168            .divider({ strokeWidth: 0.5, color: '#33000000', startMargin: 0, endMargin: 12 })
169          }
170
171          Column() {
172            Button({ type: ButtonType.Capsule, stateEffect: true }) {
173              Text($r('app.string.cancel'))
174                .fontSize($r('sys.float.ohos_id_text_size_sub_title2'))
175                .fontColor('#1095E8')
176                .fontWeight(FontWeight.Medium)
177                .height('100%')
178                .height('100%')
179            }
180            .width('100%')
181            .height('100%')
182            .backgroundColor('#00ffffff')
183            .onClick(() => {
184              if (this.controller) {
185                this.controller.close();
186              }
187            })
188          }
189          .height(56)
190          .width('100%')
191          .margin({ top: 8 }).padding({ bottom: 16 })
192        }
193        .width('100%')
194        .backgroundColor(Color.White)
195        .padding({ left: 24, right: 24 })
196        .borderRadius($r('sys.float.ohos_id_corner_radius_default_xl'))
197        .useSizeType({
198          xs: { span: 4, offset: this.useSizeTypeOffset },
199          sm: { span: 4, offset: this.useSizeTypeOffset },
200          md: { span: 4, offset: this.useSizeTypeOffset },
201          lg: { span: 4, offset: this.useSizeTypeOffset }
202        })
203      }.width('100%')
204    }
205  }
206}