1/* 2 * Copyright (c) 2022 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 router from '@system.router'; 17import { Log } from '@ohos/base/src/main/ets/utils/Log'; 18import { Action } from '../../../common/view/browserOperation/Action'; 19import { Constants } from '../../../common/model/common/Constants'; 20import { ThirdSelectPhotoBrowserActionBar } from '../../../common/view/ThirdSelectPhotoBrowserActionBar'; 21import { PhotoBrowserBg } from '@ohos/browser/src/main/ets/components/PhotoBrowserBg'; 22import { Constants as PhotoConstants } from '@ohos/browser/src/main/ets/constants/Constants'; 23import { Broadcast } from '@ohos/base/src/main/ets/utils/Broadcast'; 24import broadcastManager from '@ohos/base/src/main/ets/manager/BroadcastManager'; 25import { BroadcastConstants } from '@ohos/base/src/main/ets/constants/BroadcastConstants'; 26import { PhotoSwiper } from '@ohos/browser/src/main/ets/components/PhotoSwiper'; 27import screenManager from '@ohos/base/src/main/ets/manager/ScreenManager'; 28import mMultimodalInputManager from '@ohos/base/src/main/ets/manager/MultimodalInputManager'; 29import { GroupItemDataSource } from '@ohos/base/src/main/ets/vm/GroupItemDataSource'; 30import { MediaDataItem } from '@ohos/base/src/main/ets/data/MediaDataItem'; 31import { MediaConstants } from '@ohos/base/src/main/ets/constants/MediaConstants'; 32import { terminateSelfWithResult } from '@ohos/base/src/main/ets/utils/AbilityUtils'; 33import { SelectUtil } from '@ohos/base/src/main/ets/utils/SelectUtil'; 34import { getResourceString } from '@ohos/base/src/main/ets/utils/ResourceUtils'; 35import { showToast } from '@ohos/base/src/main/ets/utils/UiUtil'; 36// third selection photoBrowser 37 38const TAG = "ThirdSelectPhotoBrowser" 39 40@Entry 41@Component 42struct ThirdSelectPhotoBrowser { 43 @Provide browserBackgroundColor: Resource = $r('app.color.default_background_color'); 44 @Provide('selectedCount') totalSelectedCount: number = 0; 45 @Provide broadCast: Broadcast = new Broadcast(); 46 @Provide isSelected: boolean = false; 47 @Provide isShowBar: boolean = true; 48 @Provide isPullingDown: boolean = false; 49 @Provide moreMenuList: Array<Action> = new Array<Action>(); 50 @Provide pageFrom: number = Constants.ENTRY_FROM.NORMAL; 51 @Provide canSwipe: boolean = true; 52 isMultiPick = true; 53 thirdSelectTransition: string; 54 controller: SwiperController = new SwiperController(); 55 @Provide('transitionIndex') currentIndex: number = 0; 56 isFromFa: boolean = false; 57 bundleName: string = ""; 58 isSelectUpperLimited: boolean = false; 59 60 // position 61 thirdSelectPosition: number; 62 private appBroadcast: Broadcast = broadcastManager.getBroadcast(); 63 private browserDataSource: GroupItemDataSource = new GroupItemDataSource(); 64 65 aboutToAppear(): void { 66 Log.info(TAG, 'photoBrowser aboutToAppear'); 67 screenManager.setNavigationBarColor('#FFF1F3F5', '#FF000000'); 68 this.browserBackgroundColor = $r('app.color.black'); 69 mMultimodalInputManager.registerListener((control: number) => { 70 Log.info(TAG, `key control : ${control} index ${this.currentIndex}`); 71 if (control == 0) { 72 if (this.currentIndex > 0) { 73 this.onPhotoChanged(this.currentIndex - 1); 74 } 75 } else if (control == 1) { 76 if (this.currentIndex < this.browserDataSource.totalCount() - 1) { 77 this.onPhotoChanged(this.currentIndex + 1); 78 } 79 } else { 80 this.onBackPress(); 81 } 82 }); 83 let params = router.getParams(); 84 if (params) { 85 this.onPhotoChanged(parseInt(params.position.toString())); 86 this.thirdSelectTransition = params.transition.toString(); 87 this.isFromFa = params.isFromFa && true; 88 this.browserDataSource.setSelectType(params.isFromFa ? MediaConstants.SELECT_TYPE_IMAGE : MediaConstants.SELECT_TYPE_ALL); 89 this.browserDataSource.setAlbumId(params.albumId ? params.albumId.toString() : ""); 90 this.isMultiPick = params.isMultiPick as boolean; 91 this.bundleName = params.bundleName.toString(); 92 this.isSelectUpperLimited = params.isSelectUpperLimited as boolean; 93 } 94 this.browserDataSource.groupDataItem = AppStorage.Get(Constants.APP_KEY_PHOTO_BROWSER); 95 if (this.isMultiPick == true) { 96 this.totalSelectedCount = this.browserDataSource.getSelectedCount(); 97 } 98 99 this.onMenuClicked = this.onMenuClicked.bind(this); 100 101 this.broadCast.on(PhotoConstants.TOGGLE_BAR, () => { 102 this.onToggleBars(); 103 }); 104 this.broadCast.on(PhotoConstants.PULL_DOWN_END, () => { 105 this.onBackPress(); 106 }); 107 108 this.broadCast.on(PhotoConstants.DATA_SIZE_CHANGED, (size: number) => { 109 this.onDataSizeChanged(size); 110 }); 111 this.broadCast.on(PhotoConstants.DATA_CONTENT_CHANGED, () => { 112 this.onPhotoChanged(this.currentIndex); 113 }); 114 this.broadCast.on(PhotoConstants.SET_DISABLE_SWIPE, (value: boolean) => { 115 Log.info(TAG, `set swiper swipe ${value}`); 116 this.canSwipe = value; 117 }); 118 } 119 120 aboutToDisappear(): void { 121 this.broadCast.off(null, null); 122 screenManager.setNavigationBarColor('#00FFFFFF', '#FF000000'); 123 this.broadCast.release(); 124 mMultimodalInputManager.unregisterListener(); 125 this.controller = undefined; 126 } 127 128 onToggleBars() { 129 } 130 131 onDataSizeChanged(size: number): void { 132 Log.info(TAG, `onDataSizeChanged, size is ${size}`); 133 if (size == 0) { 134 this.onBackPress(); 135 } 136 } 137 138 onPhotoChanged(index: number): void { 139 this.currentIndex = index; 140 let currentPhoto = this.getCurrentPhoto(); 141 if (currentPhoto == undefined) { 142 Log.warn(TAG, 'onPhotoChanged, item is undefined'); 143 } else { 144 this.isSelected = currentPhoto.isSelect; 145 Log.info(TAG, `onPhotoChanged, index: ${index}, currentPhoto: ${currentPhoto.uri}`); 146 } 147 } 148 149 async selectStateChange() { 150 Log.info(TAG, 'change selected.'); 151 let currentPhoto = this.getCurrentPhoto(); 152 if (currentPhoto == undefined) { 153 return; 154 } 155 if (!this.isSelectUpperLimited || currentPhoto.isSelect) { 156 currentPhoto.setSelect(!currentPhoto.isSelect); 157 this.isSelected = currentPhoto.isSelect; 158 this.totalSelectedCount = this.browserDataSource.getSelectedCount(); 159 } else { 160 let toastMsg = await getResourceString($r('app.string.up_to_limit_tips')); 161 showToast(toastMsg); 162 } 163 this.broadCast.emit(BroadcastConstants.SELECT, [this.currentIndex]); 164 Log.info(TAG, `totalSelectedCount: ${this.totalSelectedCount} after state change`); 165 } 166 167 onPageShow() { 168 this.appBroadcast.emit(BroadcastConstants.THIRD_ROUTE_PAGE, []); 169 } 170 171 onPageHide() { 172 } 173 174 onMenuClicked(action: Action) { 175 Log.info(TAG, `onMenuClicked, action: ${action.actionID}`); 176 switch (action) { 177 case Action.BACK: 178 this.onBackPress(); 179 return; 180 case Action.MATERIAL_SELECT: 181 Log.info(TAG, 'click UN_SELECTED'); 182 this.selectStateChange(); 183 return; 184 case Action.SELECTED: 185 Log.info(TAG, 'click SELECTED'); 186 this.selectStateChange(); 187 return; 188 case Action.OK: 189 Log.info(TAG, 'click OK'); 190 this.setPickResult(); 191 break; 192 default: 193 break; 194 } 195 } 196 197 getCurrentPhoto(): MediaDataItem { 198 return this.browserDataSource.getDataByIndex(this.currentIndex); 199 } 200 201 onBackPress() { 202 router.back({ params: { index: this.currentIndex } }); 203 return true; 204 } 205 206 build() { 207 Stack({ alignContent: Alignment.TopStart }) { 208 PhotoBrowserBg() 209 PhotoSwiper({ 210 dataSource: this.browserDataSource, 211 photoSwiperTransition: this.thirdSelectTransition, 212 onPhotoChanged: this.onPhotoChanged.bind(this), 213 swiperController: this.controller 214 }) 215 ThirdSelectPhotoBrowserActionBar({ 216 isMultiPick: this.isMultiPick, 217 onMenuClicked: this.onMenuClicked 218 }).sharedTransition("thirdSelectPhotoBrowserActionBar", { 219 type: SharedTransitionEffectType.Static, 220 duration: Constants.SHARE_TRANSITION_DURATION, 221 zIndex: 2, 222 }) 223 } 224 } 225 226 private setPickResult() { 227 Log.debug(TAG, `setPickResult ${this.isFromFa}`); 228 if (this.isFromFa) { 229 this.appBroadcast.emit(BroadcastConstants.SAVE_FORM_EDITOR_DATA, 230 [AppStorage.Get(Constants.FORM_ITEM_NAME), AppStorage.Get(Constants.FORM_ITEM_ALBUM_ID), 231 AppStorage.Get(Constants.FORM_ITEM_DISPLAY_NAME), this.currentIndex, false]); 232 return; 233 } 234 let uriArray = new Array<string>(); 235 if (this.isMultiPick) { 236 uriArray = this.browserDataSource.getSelectedUris(); 237 Log.info(TAG, `uri size: ${uriArray}`); 238 } else { 239 let currentPhoto = this.getCurrentPhoto(); 240 if (currentPhoto == undefined) { 241 return; 242 } 243 uriArray = [currentPhoto.uri]; 244 } 245 246 let abilityResult = { 247 'resultCode': 0, 248 'want': { 249 'parameters': { 250 'select-item-list': uriArray, 251 } 252 } 253 }; 254 Log.info(TAG, `terminateSelfWithResult result: ${JSON.stringify(abilityResult)}`); 255 SelectUtil.grantPermissionForUris(uriArray, this.bundleName); 256 try { 257 Log.info(TAG, `grant permission success.`); 258 globalThis.appContext.terminateSelfWithResult(abilityResult).then((result) => { 259 Log.info(TAG, `terminateSelf result: ${result}`); 260 }); 261 } catch (err) { 262 Log.error(TAG, `grant permission error: ${JSON.stringify(err)}`); 263 }; 264 } 265 266 pageTransition() { 267 PageTransitionEnter({ type: RouteType.None, duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION }) 268 .opacity(0) 269 PageTransitionExit({ duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION }) 270 .opacity(0) 271 } 272} 273