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