• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 '@system.router';
17import { RouterOptions } from '@system.router';
18import { Log } from '../utils/Log';
19import { getResourceString } from '../utils/ResourceUtils';
20import { BroadcastConstants } from '../constants/BroadcastConstants';
21import { MenuOperationCallback } from './MenuOperationCallback';
22import { MenuOperation } from './MenuOperation';
23import { MenuContext } from './MenuContext';
24import { JumpSourceToMain } from '../models/JumpSourceToMain';
25import { SimpleAlbumDataItem } from '../common/SimpleAlbumDataItem';
26import { showToast } from '../utils/UiUtil';
27import { userFileModel } from '../base/UserFileModel';
28import { AlbumDataItem } from '../common/AlbumDataItem';
29import { LazyItem } from '../common/ItemDataSource';
30import { MediaConstants } from '../constants/MediaConstants';
31import { AlbumsDataSource } from '../common/AlbumsDataSource';
32
33const TAG = 'AlbumSetNewMenuOperation';
34
35export class AlbumSetNewMenuOperation implements MenuOperation, MenuOperationCallback {
36  private menuContext: MenuContext;
37  private onOperationEnd: Function;
38
39  constructor(menuContext: MenuContext) {
40    this.menuContext = menuContext;
41  }
42
43  doAction(): void {
44    if (this.menuContext == null) {
45      Log.warn(TAG, 'menuContext is null, return');
46      return;
47    }
48    getResourceString($r('app.string.album_new_album')).then<void, void>((name: string): void => {
49      Log.info(TAG, 'The display name is ' + name);
50      let newAlbumDisplayName = this.getNewAlbumDefaultName(name);
51      Log.info(TAG, `The display name of new album is ${newAlbumDisplayName}`);
52      this.confirmCallback = (displayName: string): Promise<void> => this.confirmCallbackBindImpl(displayName);
53      this.cancelCallback = (): void => this.cancelCallbackBindImpl();
54
55      this.menuContext.broadCast.emit(BroadcastConstants.SHOW_NEW_ALBUM_PHOTO_DIALOG,
56          [newAlbumDisplayName, this.confirmCallback, this.cancelCallback]);
57    })
58  }
59
60  private async confirmCallback(displayName: string): Promise<void> {
61    return await this.confirmCallbackBindImpl(displayName);
62  }
63
64  private async confirmCallbackBindImpl(displayName: string): Promise<void> {
65    Log.info(TAG, 'AlbumSet new album confirm and the new name is: ' + displayName);
66    let simpleAlbumDataItem: SimpleAlbumDataItem = new SimpleAlbumDataItem('', displayName, '', '', '', -1, -1);
67    if (displayName != undefined && displayName != null) {
68      let isExit = await this.checkAlbumExit(simpleAlbumDataItem);
69      if (isExit) {
70        getResourceString($r('app.string.name_already_use')).then<void, void>((message: string): void => {
71            showToast(message);
72        })
73        return;
74      }
75    }
76    this.onOperationEnd = this.menuContext.onOperationEnd;
77    let onOperationStart: Function = this.menuContext.onOperationStart;
78    if (onOperationStart != null) onOperationStart();
79
80    if (this.menuContext.jumpSourceToMain === JumpSourceToMain.ALBUM) {
81      Log.info(TAG, 'go back to photo grid');
82      this.menuContext.broadCast.emit(BroadcastConstants.MEDIA_OPERATION, [simpleAlbumDataItem, (): void => this.onCompletedBindImpl()]);
83    } else {
84      let params: Object = {
85        albumInfo: JSON.stringify(simpleAlbumDataItem),
86        isNewAlbum: true
87      };
88      let routerOptions: RouterOptions = {
89        uri: 'pages/AlbumSelect',
90        params: params
91      };
92      router.push(routerOptions);
93      this.onCompleted();
94    }
95  }
96
97  private async checkAlbumExit(simpleAlbumDataItem: SimpleAlbumDataItem): Promise<boolean> {
98    return await userFileModel.getUserAlbumCountByName(simpleAlbumDataItem.displayName) > 0;
99  }
100
101  private cancelCallback(): void {
102    this.cancelCallbackBindImpl();
103  }
104
105  private cancelCallbackBindImpl(): void {
106    Log.info(TAG, 'AlbumSet new album cancel');
107  }
108
109  onCompleted(): void {
110    this.onCompletedBindImpl();
111  }
112
113  private onCompletedBindImpl(): void {
114    Log.info(TAG, 'new album data succeed!');
115    if (this.onOperationEnd != null) this.onOperationEnd();
116  }
117
118  onError(): void {
119    Log.error(TAG, 'new album data failed!');
120    if (this.onOperationEnd != null) this.onOperationEnd();
121  }
122
123  private checkAndAddNumber(albumInfo: AlbumDataItem, prefixName: string, numbers: number[]): void {
124    let res = albumInfo.displayName.match(new RegExp('^' + prefixName + '[1-9][0-9]*$'));
125    Log.info(TAG, `check name res ${res}`);
126    if (res) {
127      let number = res[0].match(new RegExp(`[1-9][0-9]*`));
128      numbers.push(parseInt(number[0]));
129    }
130  }
131
132  private getNewAlbumDefaultName(prefixName: string): string {
133    let numbers: number[] = [];
134    for (let i = 0; i < this.menuContext.dataSource.totalCount(); i++) {
135      let album = this.menuContext.dataSource as AlbumsDataSource;
136      this.checkAndAddNumber(album.getDataByIndex(i), prefixName, numbers);
137    }
138
139    Log.debug(TAG, `${JSON.stringify(numbers)}`);
140
141    if (numbers.length <= 0) {
142      return `${prefixName}1`;
143    } else if (numbers.length === 1) {
144      if (numbers[0] - 1 > 0) {
145        return `${prefixName}1`;
146      } else {
147        return `${prefixName}${numbers[0] + 1}`;
148      }
149    }
150
151    numbers.sort(function (a, b) {
152      return a - b;
153    });
154
155    if (numbers[0] - 1 > 0) {
156      return `${prefixName}1`;
157    }
158
159    for (let i = 1; i < numbers.length; i++) {
160      let res = numbers[i - 1] + 1;
161      if (res < numbers[i]) {
162        return `${prefixName}${res}`;
163      }
164    }
165    return `${prefixName}${numbers[numbers.length - 1] + 1}`;
166  }
167}
168