1/* 2 * Copyright (c) 2022-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 { Log } from '../../utils/Log'; 17import { BroadCastConstants } from '../../model/common/BroadCastConstants'; 18import type { MenuOperationCallback } from './MenuOperationCallback'; 19import type { MenuOperation } from './MenuOperation'; 20import { MenuContext } from './MenuContext'; 21import { JumpSourceToMain } from '../../model/browser/photo/JumpSourceToMain'; 22import { AlbumInfo } from '../../model/browser/album/AlbumInfo'; 23import router from '@ohos.router'; 24import { UiUtil } from '../../utils/UiUtil'; 25import { AlbumDefine } from '../../model/browser/AlbumDefine'; 26import { BrowserDataFactory } from '../../interface/BrowserDataFactory'; 27import { BigDataConstants, ReportToBigDataUtil } from '../../utils/ReportToBigDataUtil'; 28import { Album, UserFileManagerAccess } from '../../access/UserFileManagerAccess'; 29 30const TAG: string = 'common_AlbumSetNewMenuOperation'; 31 32export class AlbumSetNewMenuOperation implements MenuOperation, MenuOperationCallback { 33 private menuContext: MenuContext; 34 private defaultAlbumName: string; 35 private onOperationEnd: Function; 36 37 constructor(menuContext: MenuContext) { 38 this.menuContext = menuContext; 39 } 40 41 async doAction(): Promise<void> { 42 if (this.menuContext == null) { 43 Log.error(TAG, 'menuContext is null, return'); 44 return; 45 } 46 let msg = { 47 'Type': BigDataConstants.ALBUM_CREATE 48 }; 49 ReportToBigDataUtil.report(BigDataConstants.ALBUM_OPERATION_ID, msg); 50 51 let a = $r('app.string.album_new_album'); 52 Log.info(TAG, `The display name from resource ${JSON.stringify(a)}`); 53 this.defaultAlbumName = ''; 54 try { 55 let context = globalThis.photosAbilityContext; 56 if (context == null || context === 'undefined') { 57 Log.info(TAG, 'context is null!'); 58 } else { 59 this.defaultAlbumName = await context.resourceManager.getString(a.id); 60 Log.info(TAG, `The display name is ${this.defaultAlbumName}`); 61 let newAlbumDisplayName 62 = this.getNewAlbumDefaultName(this.defaultAlbumName); 63 Log.info(TAG, `The display name of new album is ${newAlbumDisplayName}`); 64 65 this.confirmCallback = this.confirmCallback.bind(this); 66 this.cancelCallback = this.cancelCallback.bind(this); 67 68 this.menuContext.broadCast.emit(BroadCastConstants.SHOW_NEW_ALBUM_PHOTO_DIALOG, 69 [newAlbumDisplayName, this.confirmCallback, this.cancelCallback]); 70 } 71 } catch (error) { 72 let msg = { 73 'Type': BigDataConstants.ALBUM_CREATE_ERROR, 74 'errMsg': JSON.stringify(error) 75 }; 76 ReportToBigDataUtil.errEventReport(BigDataConstants.ALBUM_OPERATION_ERROR_ID, msg); 77 Log.info(TAG, `The display name error ${error}`); 78 } 79 } 80 81 onCompleted(): void { 82 Log.info(TAG, 'new album data succeed!'); 83 this.onOperationEnd && this.onOperationEnd(); 84 } 85 86 onError(): void { 87 Log.error(TAG, 'new album data failed!'); 88 this.onOperationEnd && this.onOperationEnd(); 89 } 90 91 private async confirmCallback(displayName: string): Promise<boolean> { 92 Log.info(TAG, `AlbumSet new album confirm and the new name is: ${displayName}`); 93 if (displayName) { 94 // 过滤用户相册 95 let targetAlbum: Album = await UserFileManagerAccess.getInstance().getAlbumByName(displayName); 96 // 过滤系统相册 97 let isAlbumNameExistInSystemAlbums: boolean = await UserFileManagerAccess.getInstance() 98 .isAlbumNameExistInSystemAlbums(displayName); 99 if (targetAlbum || isAlbumNameExistInSystemAlbums) { 100 UiUtil.showToast($r('app.string.name_already_use')); 101 return false; 102 } 103 } 104 this.onOperationEnd = this.menuContext.onOperationEnd; 105 let onOperationStart: Function = this.menuContext.onOperationStart; 106 onOperationStart && onOperationStart(); 107 108 let album: Album = await UserFileManagerAccess.getInstance().createUserAlbum(displayName); 109 if (this.menuContext.jumpSourceToMain == JumpSourceToMain.ALBUM) { 110 Log.info(TAG, 'go back to photo grid'); 111 this.menuContext.broadCast.emit(BroadCastConstants.MEDIA_OPERATION, 112 [displayName, album.albumUri, this.onCompleted.bind(this)]); 113 } else { 114 router.pushUrl({ 115 url: 'pages/AlbumSelect', 116 params: { 117 albumName: displayName, 118 albumUri: album.albumUri, 119 isNewAlbum: true 120 } 121 }); 122 this.onCompleted(); 123 } 124 return true; 125 } 126 127 private cancelCallback(): void { 128 Log.info(TAG, 'AlbumSet new album cancel'); 129 } 130 131 private checkAndAddNumber(albumInfo: AlbumInfo, prefixName: string, numbers: number[]): void { 132 let res = albumInfo.albumName.match(new RegExp('^' + prefixName + '[1-9][0-9]*$')); 133 Log.info(TAG, `check name res ${res}`) 134 if (res) { 135 let number = res[0].match(new RegExp(`[1-9][0-9]*`)); 136 numbers.push(parseInt(number[0])); 137 } 138 } 139 140 private getNewAlbumDefaultName(prefixName: string): string { 141 let numbers: number[] = []; 142 for (let i = 0; i < this.menuContext.albumSetDataSource.totalCount(); i++) { 143 this.checkAndAddNumber(this.menuContext.albumSetDataSource.getData(i).data, prefixName, numbers); 144 } 145 let currentAlbum = this.menuContext.albumInfo; 146 if (currentAlbum != null) { 147 this.checkAndAddNumber(currentAlbum, prefixName, numbers); 148 } 149 150 Log.debug(TAG, `${JSON.stringify(numbers)}`); 151 152 if (numbers.length <= 0) { 153 return `${prefixName}1`; 154 } else if (numbers.length == 1) { 155 if (numbers[0] - 1 > 0) { 156 return `${prefixName}1`; 157 } else { 158 return `${prefixName}${numbers[0] + 1}`; 159 } 160 } 161 162 numbers.sort(function (a, b) { 163 return a - b; 164 }); 165 166 if (numbers[0] - 1 > 0) { 167 return `${prefixName}1`; 168 } 169 170 for (let i = 1; i < numbers.length; i++) { 171 let res = numbers[i - 1] + 1; 172 if (res < numbers[i]) { 173 return `${prefixName}${res}`; 174 } 175 } 176 return `${prefixName}${numbers[numbers.length - 1] + 1}`; 177 } 178}