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}