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 router from '@ohos.router'; 17import { MediaOperationType } from '../../model/common/MediaOperationType'; 18import { MediaOperationActionBar } from './MediaOperationActionBar'; 19import { Log } from '../../utils/Log'; 20import { BroadCast } from '../../utils/BroadCast'; 21import { AlbumSetNewMenuOperation } from './AlbumSetNewMenuOperation'; 22import { MenuOperationFactory } from '../../interface/MenuOperationFactory'; 23import { AlbumSetDataSource } from '../../model/browser/album/AlbumSetDataSource'; 24import { AlbumInfo } from '../../model/browser/album/AlbumInfo'; 25import { BroadCastConstants } from '../../model/common/BroadCastConstants'; 26import { AlbumListCard } from './AlbumListCard'; 27import { MenuContext } from './MenuContext'; 28import { Action } from './Action'; 29import { JumpSourceToMain } from '../../model/browser/photo/JumpSourceToMain'; 30import { CustomDialogView } from '../dialog/CustomDialogView'; 31import { AlbumDefine } from '../../model/browser/AlbumDefine'; 32import { ColumnSize, ScreenManager } from '../../model/common/ScreenManager'; 33import { Constants } from '../../model/common/Constants'; 34import { AlbumSetDataInfo } from '../../model/common/AlbumSetDataInfo'; 35import { UserFileManagerAccess } from '../../access/UserFileManagerAccess'; 36import { MediaItem } from '../../model/browser/photo/MediaItem'; 37import { UiUtil } from '../../utils/UiUtil'; 38 39const TAG: string = 'common_MediaOperationBasePage'; 40 41@Component 42export struct MediaOperationBasePage { 43 @StorageLink('leftBlank') leftBlank: [number, number, number, number] 44 = [0, ScreenManager.getInstance().getStatusBarHeight(), 0, ScreenManager.getInstance().getNaviBarHeight()]; 45 @Provide pageType: string = MediaOperationType.Move; 46 @Provide broadCast: BroadCast = new BroadCast(); 47 @Provide loadingFinish: boolean = false; 48 @State screenHeight: number = ScreenManager.getInstance().getWinHeight(); 49 @State listCardWidth: number = 0; 50 @State listCardPaddingBottom: number = 24; 51 scroller: Scroller = new Scroller(); 52 albums: AlbumSetDataSource; 53 isActive: boolean = false; // Whether the page is in the foreground 54 sourceAlbumUri: string; 55 currentAlbum: AlbumInfo; 56 private pageFrom: string; 57 private selectedItems: Array<MediaItem> = []; 58 private mediaType: number; 59 private listCardBorderRadius: number = 16; 60 onWindowSizeChangeCallBack = () => this.updateListCardWidth(); 61 62 aboutToAppear(): void { 63 Log.info(TAG, `aboutToAppear`); 64 UiUtil.getResourceNumber($r('sys.float.ohos_id_default_padding_bottom_fixed')).then((value: number) => { 65 this.listCardPaddingBottom = px2vp(value); 66 }); 67 this.albums = new AlbumSetDataSource(this.broadCast, { moreInfo: true }); 68 this.albums.setMultiParameter(true); 69 let param: any = router.getParams(); 70 if (param) { 71 Log.info(TAG, `router getParams ${JSON.stringify(param)}`); 72 this.pageType = param.pageType; 73 this.pageFrom = param.pageFrom 74 this.currentAlbum = param.albumInfo; 75 if (this.currentAlbum != null) { 76 this.sourceAlbumUri = this.currentAlbum.uri; 77 } 78 switch (this.pageFrom) { 79 case Constants.MEDIA_OPERATION_FROM_PHOTO_BROWSER: 80 this.mediaType = param.mediaType; 81 break; 82 case Constants.MEDIA_OPERATION_FROM_TIMELINE: 83 this.selectedItems = param.selectedItems; 84 break; 85 case Constants.MEDIA_OPERATION_FROM_PHOTO_GRID: 86 this.selectedItems = param.selectedItems; 87 break; 88 default: 89 break; 90 } 91 } 92 this.albums.setFilterAlbumsFunction(this.filterAlbumInList.bind(this)); 93 this.onActive(); 94 this.onMenuClicked = this.onMenuClicked.bind(this); 95 96 this.broadCast.on(Constants.ON_LOADING_FINISHED, (totalCount) => { 97 this.loadingFinish = true; 98 }); 99 100 ScreenManager.getInstance().on(ScreenManager.ON_WIN_SIZE_CHANGED, this.onWindowSizeChangeCallBack); 101 102 this.broadCast.on(BroadCastConstants.MEDIA_OPERATION, (displayName: string, albumUri: string, completedFunc?: Function) => { 103 Log.info(TAG, `broadCast on mediaOperation, albumName: ${displayName}, albumUri: ${albumUri}`); 104 router.back({ 105 url: '', 106 params: { 107 pageType: this.pageType, 108 albumName: displayName, 109 albumUri: albumUri 110 } 111 }); 112 completedFunc && completedFunc(); 113 }); 114 this.albums.updateAlbumMediaCount(); 115 this.updateListCardWidth(); 116 Log.info(TAG, `album mediaSet ${this.albums.mediaSetList}`); 117 } 118 119 aboutToDisappear(): void { 120 Log.info(TAG, 'aboutToDisappear'); 121 this.broadCast.off(null, null); 122 ScreenManager.getInstance().off(ScreenManager.ON_WIN_SIZE_CHANGED, this.onWindowSizeChangeCallBack); 123 this.onWindowSizeChangeCallBack = null; 124 } 125 126 onMenuClicked(action: Action) { 127 Log.info(TAG, `onMenuClicked, actionID: ${action.actionID}`); 128 129 switch (action.actionID) { 130 case Action.CANCEL.actionID: 131 router.back({ 132 url: '', 133 params: {} 134 }); 135 break; 136 case Action.NEW.actionID: 137 this.createNewAlbum(); 138 break; 139 default: 140 break; 141 } 142 } 143 144 createNewAlbum() { 145 Log.info(TAG, 'createNewAlbum'); 146 let menuContext = new MenuContext(); 147 this.onOperationStart = this.onOperationStart.bind(this); 148 this.onOperationEnd = this.onOperationEnd.bind(this); 149 menuContext 150 .withOperationStartCallback(this.onOperationStart) 151 .withOperationEndCallback(this.onOperationEnd) 152 .withAlbumSetDataSource(this.albums) 153 .withAlbumInfo(this.currentAlbum) 154 .withBroadCast(this.broadCast) 155 .withJumpSourceToMain(JumpSourceToMain.ALBUM); 156 let menuOperation 157 = MenuOperationFactory.getInstance().createMenuOperation(AlbumSetNewMenuOperation, menuContext); 158 menuOperation.doAction(); 159 } 160 161 onOperationStart() { 162 } 163 164 onOperationEnd() { 165 } 166 167 updateListCardWidth(): void { 168 let screenColumns: number = ScreenManager.getInstance().getScreenColumns(); 169 Log.info(TAG, `updateListCardWidth start ${screenColumns}`); 170 if (screenColumns == ColumnSize.COLUMN_FOUR) { 171 this.listCardWidth = ScreenManager.getInstance().getColumnsWidth(ColumnSize.COLUMN_FOUR); 172 } else if (screenColumns == ColumnSize.COLUMN_EIGHT) { 173 this.listCardWidth = ScreenManager.getInstance().getColumnsWidth(ColumnSize.COLUMN_SIX); 174 } else if (screenColumns == ColumnSize.COLUMN_TWELVE) { 175 this.listCardWidth = ScreenManager.getInstance().getColumnsWidth(ColumnSize.COLUMN_EIGHT); 176 } else { 177 Log.error(TAG, 'screenColumns is not init'); 178 } 179 Log.info(TAG, `updateListCardWidth ${this.listCardWidth}`); 180 } 181 182 // Callback when the page is in the foreground 183 onActive() { 184 if (!this.isActive) { 185 Log.info(TAG, 'onActive'); 186 this.isActive = true; 187 this.albums && this.albums.onActive(); 188 } 189 } 190 191 isSelectedItemsContainsVideo(): boolean { 192 for (let i = 0; i < this.selectedItems.length; i++) { 193 let item = this.selectedItems[i]; 194 if (item.mediaType === UserFileManagerAccess.MEDIA_TYPE_VIDEO) { 195 Log.info(TAG, 'Selected items contains video.'); 196 return true; 197 } 198 } 199 Log.info(TAG, 'Selected items are all images.'); 200 return false; 201 } 202 203 filterAlbumInList(mediaSetList: AlbumInfo[]): Array<AlbumInfo> { 204 Log.info(TAG, 'Judge if the album be shown.'); 205 if (!mediaSetList) { 206 Log.warn(TAG, 'Album data info undefined'); 207 return []; 208 } 209 let res = mediaSetList.filter((item) => { 210 return!item.isSystemAlbum && item.uri !== this.sourceAlbumUri; 211 }); 212 return res; 213 } 214 215 getBorderRadius(index: number): BorderRadiuses { 216 if (index === 0 && index + 1 === this.albums.totalCount()) { 217 return { 218 topLeft: this.listCardBorderRadius, 219 topRight: this.listCardBorderRadius, 220 bottomLeft: this.listCardBorderRadius, 221 bottomRight: this.listCardBorderRadius 222 }; 223 } else if (index + 1 === this.albums.totalCount()) { 224 return { bottomLeft: this.listCardBorderRadius, bottomRight: this.listCardBorderRadius }; 225 } else if (index === 0) { 226 return { topLeft: this.listCardBorderRadius, topRight: this.listCardBorderRadius }; 227 } 228 } 229 230 build() { 231 Column() { 232 MediaOperationActionBar({ onMenuClicked: this.onMenuClicked }) 233 234 Stack() { 235 List({ scroller: this.scroller }) { 236 LazyForEach(this.albums, (albumSetDataInfo: AlbumSetDataInfo, index?: number) => { 237 ListItem() { 238 AlbumListCard({ 239 item: albumSetDataInfo.data, 240 index: albumSetDataInfo.index 241 }) 242 } 243 .key('MediaOperationPageAlbum' + index) 244 .width(this.listCardWidth) 245 .backgroundColor($r('sys.color.ohos_id_color_card_bg')) 246 .padding({ 247 left: $r('app.float.list_card_margin') 248 }) 249 .borderRadius(this.getBorderRadius(index)) 250 }, (item) => item.data.id) 251 } 252 .alignListItem(ListItemAlign.Center) 253 .padding({ 254 top: $r('app.float.album_let_page_padding_top'), 255 bottom: this.leftBlank[3] + this.listCardPaddingBottom 256 }) 257 .scrollBar(BarState.Auto) 258 .height(Constants.PERCENT_100) 259 .width(Constants.PERCENT_100) 260 } 261 .height(Constants.PERCENT_100) 262 263 CustomDialogView({ broadCast: $broadCast }) 264 } 265 .backgroundColor($r('app.color.default_background_color')) // ux: colorSubBackground 266 .height(Constants.PERCENT_100) 267 .padding({ 268 top: this.leftBlank[1], 269 bottom: this.leftBlank[3] + Constants.ActionBarHeight 270 }) 271 } 272}