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> => this.filterAlbumInList(mediaSetList)); 117 this.onActive(); 118 119 this.broadCast.on(Constants.ON_LOADING_FINISHED, this.onLoadingFinishedFunc); 120 121 ScreenManager.getInstance().on(ScreenManager.ON_WIN_SIZE_CHANGED, this.onWindowSizeChangeCallBack); 122 123 this.broadCast.on(BroadCastConstants.MEDIA_OPERATION, this.mediaOperationFunc); 124 this.albums.updateAlbumMediaCount(); 125 this.updateListCardWidth(); 126 Log.info(TAG, `album mediaSet ${this.albums.mediaSetList}`); 127 } 128 129 aboutToDisappear(): void { 130 Log.info(TAG, 'aboutToDisappear'); 131 if(this.broadCast) { 132 this.broadCast.off(Constants.ON_LOADING_FINISHED, this.onLoadingFinishedFunc); 133 this.broadCast.off(BroadCastConstants.MEDIA_OPERATION, this.mediaOperationFunc); 134 } 135 ScreenManager.getInstance().off(ScreenManager.ON_WIN_SIZE_CHANGED, this.onWindowSizeChangeCallBack); 136 } 137 138 onMenuClicked(action: Action) { 139 Log.info(TAG, `onMenuClicked, actionID: ${action.actionID}`); 140 if (action.actionID === Action.CANCEL.actionID) { 141 router.back({ 142 url: '', 143 params: {} 144 }); 145 } else if (action.actionID === Action.NEW.actionID) { 146 this.createNewAlbum(); 147 } 148 } 149 150 createNewAlbum() { 151 Log.info(TAG, 'createNewAlbum'); 152 let menuContext = new MenuContext(); 153 menuContext 154 .withOperationStartCallback((): void => this.onOperationStart()) 155 .withOperationEndCallback((): void => this.onOperationEnd()) 156 .withAlbumSetDataSource(this.albums) 157 .withAlbumInfo(this.currentAlbum) 158 .withBroadCast(this.broadCast) 159 .withJumpSourceToMain(JumpSourceToMain.ALBUM); 160 let menuOperation 161 = MenuOperationFactory.getInstance().createMenuOperation(AlbumSetNewMenuOperation, menuContext); 162 menuOperation.doAction(); 163 } 164 165 onOperationStart() { 166 } 167 168 onOperationEnd() { 169 } 170 171 updateListCardWidth(): void { 172 let screenColumns: number = ScreenManager.getInstance().getScreenColumns(); 173 Log.info(TAG, `updateListCardWidth start ${screenColumns}`); 174 if (screenColumns == ColumnSize.COLUMN_FOUR) { 175 this.listCardWidth = ScreenManager.getInstance().getColumnsWidth(ColumnSize.COLUMN_FOUR); 176 } else if (screenColumns == ColumnSize.COLUMN_EIGHT) { 177 this.listCardWidth = ScreenManager.getInstance().getColumnsWidth(ColumnSize.COLUMN_SIX); 178 } else if (screenColumns == ColumnSize.COLUMN_TWELVE) { 179 this.listCardWidth = ScreenManager.getInstance().getColumnsWidth(ColumnSize.COLUMN_EIGHT); 180 } else { 181 Log.error(TAG, 'screenColumns is not init'); 182 } 183 Log.info(TAG, `updateListCardWidth ${this.listCardWidth}`); 184 } 185 186 // Callback when the page is in the foreground 187 onActive() { 188 if (!this.isActive) { 189 Log.info(TAG, 'onActive'); 190 this.isActive = true; 191 this.albums && this.albums.onActive(); 192 } 193 } 194 195 isSelectedItemsContainsVideo(): boolean { 196 for (let i = 0; i < this.selectedItems.length; i++) { 197 let item = this.selectedItems[i]; 198 if (item.mediaType === UserFileManagerAccess.MEDIA_TYPE_VIDEO) { 199 Log.info(TAG, 'Selected items contains video.'); 200 return true; 201 } 202 } 203 Log.info(TAG, 'Selected items are all images.'); 204 return false; 205 } 206 207 filterAlbumInList(mediaSetList: AlbumInfo[]): Array<AlbumInfo> { 208 Log.info(TAG, 'Judge if the album be shown.'); 209 if (!mediaSetList) { 210 Log.warn(TAG, 'Album data info undefined'); 211 return []; 212 } 213 let res = mediaSetList.filter((item) => { 214 return!item.isSystemAlbum && item.uri !== this.sourceAlbumUri; 215 }); 216 return res; 217 } 218 219 getBorderRadius(index: number): BorderRadiuses | undefined { 220 if (this.albums != null && index === 0 && index + 1 === this.albums.totalCount()) { 221 return { 222 topLeft: this.listCardBorderRadius, 223 topRight: this.listCardBorderRadius, 224 bottomLeft: this.listCardBorderRadius, 225 bottomRight: this.listCardBorderRadius 226 }; 227 } else if (this.albums != null && index + 1 === this.albums.totalCount()) { 228 return { bottomLeft: this.listCardBorderRadius, bottomRight: this.listCardBorderRadius }; 229 } else if (index === 0) { 230 return { topLeft: this.listCardBorderRadius, topRight: this.listCardBorderRadius }; 231 } 232 return undefined; 233 } 234 235 build() { 236 Column() { 237 MediaOperationActionBar({ onMenuClicked: this.funcOnMenuClicked }) 238 239 Stack() { 240 List({ scroller: this.scroller }) { 241 LazyForEach(this.albums as AlbumSetDataSource, (albumSetDataInfo: AlbumSetDataInfo, index?: number) => { 242 ListItem() { 243 AlbumListCard({ 244 item: albumSetDataInfo.data, 245 index: albumSetDataInfo.index 246 }) 247 } 248 .key('MediaOperationPageAlbum' + index) 249 .width(this.listCardWidth) 250 .backgroundColor($r('sys.color.ohos_id_color_card_bg')) 251 .padding({ 252 left: $r('app.float.list_card_margin') 253 }) 254 .borderRadius(this.getBorderRadius(index as number) as BorderRadiuses) 255 }, (item: AlbumSetDataInfo): string => { 256 return item.data.uri; 257 }); 258 } 259 .alignListItem(ListItemAlign.Center) 260 .padding({ 261 top: $r('app.float.album_let_page_padding_top'), 262 bottom: this.leftBlank[3] + this.listCardPaddingBottom 263 }) 264 .scrollBar(BarState.Auto) 265 .height(Constants.PERCENT_100 as string) 266 .width(Constants.PERCENT_100 as string) 267 } 268 .height(Constants.PERCENT_100 as string) 269 270 CustomDialogView({ broadCast: $broadCast }) 271 } 272 .backgroundColor($r('app.color.default_background_color')) // ux: colorSubBackground 273 .height(Constants.PERCENT_100) 274 .padding({ 275 top: this.leftBlank[1], 276 bottom: this.leftBlank[3] + Constants.ActionBarHeight 277 }) 278 } 279}