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 { RouterConstants } from '@ohos/base/src/main/ets/constants/RouterConstants'; 21import { ThirdSelectPhotoBrowserActionBar } from '../../../common/view/ThirdSelectPhotoBrowserActionBar'; 22import { PhotoBrowserBg } from '@ohos/browser/src/main/ets/components/PhotoBrowserBg'; 23import { Constants as PhotoConstants } from '@ohos/browser/src/main/ets/constants/Constants'; 24import { Broadcast } from '@ohos/base/src/main/ets/utils/Broadcast'; 25import { BroadcastConstants } from '@ohos/base/src/main/ets/constants/BroadcastConstants'; 26import broadcastManager from '@ohos/base/src/main/ets/manager/BroadcastManager'; 27import { PhotoSwiper } from '@ohos/browser/src/main/ets/components/PhotoSwiper'; 28import mMultimodalInputManager from '@ohos/base/src/main/ets/manager/MultimodalInputManager'; 29import screenManager from '@ohos/base/src/main/ets/manager/ScreenManager'; 30import { SimpleAlbumDataItem } from '@ohos/base/src/main/ets/data/SimpleAlbumDataItem'; 31import { GroupItemDataSource } from '@ohos/base/src/main/ets/vm/GroupItemDataSource'; 32import { MediaDataItem } from '@ohos/base/src/main/ets/data/MediaDataItem'; 33import { terminateSelfWithResult } from '@ohos/base/src/main/ets/utils/AbilityUtils'; 34 35const TAG = "SelectPhotoBrowser" 36// select mode 37@Entry 38@Component 39struct SelectPhotoBrowser { 40 @Provide browserBackgroundColor: Resource = $r('app.color.default_background_color'); 41 @Provide('selectedCount') totalSelectedCount: number = 0; 42 @Provide broadCast: Broadcast = new Broadcast(); 43 @Provide isSelected: boolean = true; 44 @Provide isShowBar: boolean = true; 45 @Provide isPullingDown: boolean = false; 46 @Provide moreMenuList: Array<Action> = new Array<Action>(); 47 @Provide pageFrom: number = RouterConstants.ENTRY_FROM.NORMAL; 48 @Provide canSwipe: boolean = true; 49 isMultiPick = true; 50 selectPhotoTransition: string; 51 controller: SwiperController = new SwiperController(); 52 53 // swiper currentIndex, there may not be onChanged callback during data refresh, so mediaItem cannot be saved 54 @Provide('transitionIndex') currentIndex: number = 0; 55 56 // The global Broadcast of the application process. Event registration and destruction should be paired 57 private appBroadcast: Broadcast = broadcastManager.getBroadcast(); 58 private browserDataSource: GroupItemDataSource = new GroupItemDataSource(); 59 60 aboutToAppear(): void { 61 Log.info(TAG, 'photoBrowser aboutToAppear'); 62 screenManager.setNavigationBarColor('#FFF1F3F5', '#FF000000'); 63 this.browserBackgroundColor = $r('app.color.black'); 64 mMultimodalInputManager.registerListener((control: number) => { 65 Log.info(TAG, `key control : ${control} index ${this.currentIndex}`); 66 if (control == 0) { 67 if (this.currentIndex > 0) { 68 this.onPhotoChanged(this.currentIndex - 1); 69 } 70 } else if (control == 1) { 71 if (this.currentIndex < this.browserDataSource.totalCount() - 1) { 72 this.onPhotoChanged(this.currentIndex + 1); 73 } 74 } else { 75 this.onBackPress(); 76 } 77 }); 78 let param = router.getParams(); 79 if (param.pageFrom) { 80 this.pageFrom = new Number(param.pageFrom).valueOf() || 0; 81 } 82 if (this.pageFrom == RouterConstants.ENTRY_FROM.DISTRIBUTED) { 83 this.browserDataSource.setDeviceId(param.deviceId ? param.deviceId.toString() : ''); 84 } 85 86 if (this.isMultiPick == true) { 87 this.totalSelectedCount = this.browserDataSource.getSelectedCount(); 88 } 89 if (param.albumInfo) { 90 this.browserDataSource.setAlbumId((param.albumInfo as SimpleAlbumDataItem).id); 91 } 92 93 this.browserDataSource.groupDataItem = AppStorage.Get(Constants.APP_KEY_PHOTO_BROWSER); 94 this.onPhotoChanged(new Number(param.position).valueOf() || 0); 95 this.isSelected = this.getCurrentPhoto().isSelect; 96 this.totalSelectedCount = this.browserDataSource.getSelectedCount(); 97 this.selectPhotoTransition = param.transition ? param.transition.toString() : ''; 98 this.onMenuClicked = this.onMenuClicked.bind(this); 99 100 // register event handling 101 this.broadCast.on(PhotoConstants.TOGGLE_BAR, (event) => { 102 Log.info(TAG, `TOGGLE_BAR : ${JSON.stringify(event)}`); 103 }); 104 105 this.broadCast.on(PhotoConstants.PULL_DOWN_END, (event) => { 106 Log.info(TAG, `PULL_DOWN_END : ${JSON.stringify(event)}`); 107 this.onBackPress(); 108 }); 109 110 this.broadCast.on(PhotoConstants.DATA_SIZE_CHANGED, (size: number) => { 111 this.onDataSizeChanged(size); 112 }); 113 114 this.broadCast.on(PhotoConstants.DATA_CONTENT_CHANGED, (size: number) => { 115 // onContentChanged only the current item is updated 116 Log.info(TAG, `DATA_CONTENT_CHANGED : ${size}`); 117 this.onPhotoChanged(this.currentIndex); 118 }); 119 120 this.broadCast.on(PhotoConstants.SET_DISABLE_SWIPE, (value: boolean) => { 121 Log.info(TAG, `set swiper swipe ${value}`); 122 this.canSwipe = value; 123 }); 124 } 125 126 aboutToDisappear(): void { 127 screenManager.setNavigationBarColor('#00FFFFFF', '#FF000000'); 128 this.broadCast.release(); 129 mMultimodalInputManager.unregisterListener(); 130 } 131 132 onToggleBars() { 133 } 134 135 onDataSizeChanged(size: number): void { 136 Log.info(TAG, `onDataSizeChanged, size is ${size}`); 137 if (size == 0) { 138 this.onBackPress(); 139 } 140 } 141 142 onPhotoChanged(index: number): void{ 143 this.currentIndex = index; 144 this.isSelected = this.getCurrentPhoto().isSelect; 145 this.browserDataSource.notifyDataChange(index); 146 } 147 148 private selectStateChange() { 149 Log.info(TAG, 'change selected'); 150 let currentPhoto = this.getCurrentPhoto(); 151 if (currentPhoto == undefined) { 152 return; 153 } 154 currentPhoto.setSelect(!currentPhoto.isSelect); 155 this.isSelected = currentPhoto.isSelect; 156 this.totalSelectedCount = this.browserDataSource.getSelectedCount(); 157 this.appBroadcast.emit(BroadcastConstants.UPDATE_DATA_SOURCE, [currentPhoto]); 158 Log.info(TAG, `totalSelectedCount: ${this.totalSelectedCount} after state change`); 159 } 160 161 onPageShow() { 162 Log.info(TAG, 'onPageShow'); 163 this.appBroadcast.emit(BroadcastConstants.THIRD_ROUTE_PAGE, []); 164 } 165 166 onPageHide() { 167 Log.info(TAG, 'onPageHide'); 168 } 169 170 onMenuClicked(action: Action) { 171 Log.debug(TAG, `onMenuClicked, action: ${action.actionID}`); 172 switch (action) { 173 case Action.BACK: 174 this.onBackPress(); 175 return; 176 case Action.MATERIAL_SELECT: 177 case Action.SELECTED: 178 this.selectStateChange(); 179 return; 180 case Action.OK: 181 Log.info(TAG, 'click OK'); 182 this.setPickResult(); 183 break; 184 default: 185 break; 186 } 187 } 188 189 getCurrentPhoto(): MediaDataItem { 190 return this.browserDataSource.groupDataItem[this.currentIndex]; 191 } 192 193 onBackPress() { 194 Log.info(TAG, 'onBackPress'); 195 router.back({ params: { index: this.currentIndex } }); 196 return true; 197 } 198 199 build() { 200 Stack({ alignContent: Alignment.TopStart }) { 201 PhotoBrowserBg() 202 PhotoSwiper({ 203 dataSource: this.browserDataSource, 204 photoSwiperTransition: this.selectPhotoTransition, 205 onPhotoChanged: this.onPhotoChanged.bind(this), 206 swiperController: this.controller 207 }) 208 ThirdSelectPhotoBrowserActionBar({ 209 isMultiPick: this.isMultiPick, 210 onMenuClicked: this.onMenuClicked 211 }).sharedTransition("selectPhotoBrowserActionBar", { 212 type: SharedTransitionEffectType.Static, 213 duration: Constants.SHARE_TRANSITION_DURATION, 214 zIndex: 2, 215 }) 216 } 217 } 218 219 private setPickResult(): void { 220 let uriArray: string[]; 221 if (this.isMultiPick) { 222 uriArray = this.browserDataSource.getSelectedUris(); 223 Log.debug(TAG, `uri size: ${uriArray}`); 224 } else { 225 let currentPhoto = this.getCurrentPhoto(); 226 if (currentPhoto == undefined) { 227 return; 228 } 229 uriArray = [currentPhoto.uri]; 230 } 231 let abilityResult = { 232 'resultCode': 0, 233 'want': { 234 'parameters': { 235 'select-item-list': uriArray 236 } 237 } 238 }; 239 terminateSelfWithResult(abilityResult); 240 } 241 242 pageTransition() { 243 PageTransitionEnter({ type: RouteType.None, duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION }) 244 .opacity(0) 245 PageTransitionExit({ duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION }) 246 .opacity(0) 247 } 248} 249