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 this.controller = undefined; 131 } 132 133 onToggleBars() { 134 } 135 136 onDataSizeChanged(size: number): void { 137 Log.info(TAG, `onDataSizeChanged, size is ${size}`); 138 if (size == 0) { 139 this.onBackPress(); 140 } 141 } 142 143 onPhotoChanged(index: number): void{ 144 this.currentIndex = index; 145 this.isSelected = this.getCurrentPhoto().isSelect; 146 this.browserDataSource.notifyDataChange(index); 147 } 148 149 private selectStateChange() { 150 Log.info(TAG, 'change selected'); 151 let currentPhoto = this.getCurrentPhoto(); 152 if (currentPhoto == undefined) { 153 return; 154 } 155 currentPhoto.setSelect(!currentPhoto.isSelect); 156 this.isSelected = currentPhoto.isSelect; 157 this.totalSelectedCount = this.browserDataSource.getSelectedCount(); 158 this.appBroadcast.emit(BroadcastConstants.UPDATE_DATA_SOURCE, [currentPhoto]); 159 Log.info(TAG, `totalSelectedCount: ${this.totalSelectedCount} after state change`); 160 } 161 162 onPageShow() { 163 Log.info(TAG, 'onPageShow'); 164 this.appBroadcast.emit(BroadcastConstants.THIRD_ROUTE_PAGE, []); 165 } 166 167 onPageHide() { 168 Log.info(TAG, 'onPageHide'); 169 } 170 171 onMenuClicked(action: Action) { 172 Log.debug(TAG, `onMenuClicked, action: ${action.actionID}`); 173 switch (action) { 174 case Action.BACK: 175 this.onBackPress(); 176 return; 177 case Action.MATERIAL_SELECT: 178 case Action.SELECTED: 179 this.selectStateChange(); 180 return; 181 case Action.OK: 182 Log.info(TAG, 'click OK'); 183 this.setPickResult(); 184 break; 185 default: 186 break; 187 } 188 } 189 190 getCurrentPhoto(): MediaDataItem { 191 return this.browserDataSource.groupDataItem[this.currentIndex]; 192 } 193 194 onBackPress() { 195 Log.info(TAG, 'onBackPress'); 196 router.back({ params: { index: this.currentIndex } }); 197 return true; 198 } 199 200 build() { 201 Stack({ alignContent: Alignment.TopStart }) { 202 PhotoBrowserBg() 203 PhotoSwiper({ 204 dataSource: this.browserDataSource, 205 photoSwiperTransition: this.selectPhotoTransition, 206 onPhotoChanged: this.onPhotoChanged.bind(this), 207 swiperController: this.controller 208 }) 209 ThirdSelectPhotoBrowserActionBar({ 210 isMultiPick: this.isMultiPick, 211 onMenuClicked: this.onMenuClicked 212 }).sharedTransition("selectPhotoBrowserActionBar", { 213 type: SharedTransitionEffectType.Static, 214 duration: Constants.SHARE_TRANSITION_DURATION, 215 zIndex: 2, 216 }) 217 } 218 } 219 220 private setPickResult(): void { 221 let uriArray: string[]; 222 if (this.isMultiPick) { 223 uriArray = this.browserDataSource.getSelectedUris(); 224 Log.debug(TAG, `uri size: ${uriArray}`); 225 } else { 226 let currentPhoto = this.getCurrentPhoto(); 227 if (currentPhoto == undefined) { 228 return; 229 } 230 uriArray = [currentPhoto.uri]; 231 } 232 let abilityResult = { 233 'resultCode': 0, 234 'want': { 235 'parameters': { 236 'select-item-list': uriArray 237 } 238 } 239 }; 240 terminateSelfWithResult(abilityResult); 241 } 242 243 pageTransition() { 244 PageTransitionEnter({ type: RouteType.None, duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION }) 245 .opacity(0) 246 PageTransitionExit({ duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION }) 247 .opacity(0) 248 } 249} 250