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