• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-2022 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 {
17  Log,
18  PinyinSort,
19  CheckEmptyUtils,
20  EventConstants,
21  CommonConstants,
22  BaseViewModel,
23  SettingsModel,
24  PageDesktopModel,
25  ResourceManager,
26  localEventManager,
27  layoutConfigManager,
28  FolderLayoutConfig,
29  AppItemInfo,
30  GridLayoutInfo,
31  FolderData,
32  LauncherDragItemInfo
33} from '@ohos/common';
34import { BigFolderModel } from '../model/BigFolderModel';
35import { BigFolderStyleConfig } from '../common/BigFolderStyleConfig';
36import { BigFolderConstants } from '../common/constants/BigFolderConstants';
37import { BigFolderStyleConstants } from '../common/constants/BigFolderStyleConstants';
38
39const TAG = 'BigFolderViewModel';
40
41export class BigFolderViewModel extends BaseViewModel {
42  private readonly mSettingsModel: SettingsModel;
43  private readonly mBigFolderModel: BigFolderModel;
44  private readonly mPageDesktopModel: PageDesktopModel;
45  private readonly mPinyinSort: PinyinSort;
46  private readonly mGridConfig;
47  private HEXADECIMAL_VALUE: number = 36;
48  private mPageIndex: number = 0;
49  private readonly mFolderStyleConfig: BigFolderStyleConfig;
50  private readonly mFolderLayoutConfig: FolderLayoutConfig;
51  private readonly mLocalEventListener = {
52    onReceiveEvent: (event, params) => {
53      Log.showDebug(TAG, `onReceiveEvent receive event: ${event}, params: ${JSON.stringify(params)}`);
54      const openStatus = AppStorage.get('openFolderStatus');
55      if (event === EventConstants.EVENT_BADGE_UPDATE && (openStatus == BigFolderConstants.OPEN_FOLDER_STATUS_OPEN || openStatus == BigFolderConstants.OPEN_FOLDER_STATUS_STATIC)) {
56        const openFolderData: FolderData = AppStorage.get('openFolderData');
57        this.updateBadge(openFolderData, params);
58      } else if (event === EventConstants.EVENT_FOLDER_PACKAGE_REMOVED) {
59        this.deleteAppFromFolderByUninstall(params);
60      } else if (event === EventConstants.EVENT_OPEN_FOLDER_TO_CLOSE) {
61        this.closeFolder();
62      }
63    }
64  };
65
66  // badge will be designed lastly
67  private updateBadge(openFolderData: FolderData, params: AppItemInfo): void {
68    for (let i = 0; i < openFolderData.layoutInfo.length; i++) {
69      const appInfo: AppItemInfo = openFolderData.layoutInfo[i].find(item => {
70        return item.bundleName === params.bundleName;
71      });
72      if (appInfo !== undefined && appInfo.bundleName.length > 0) {
73        const index = openFolderData.layoutInfo[i].indexOf(appInfo);
74        appInfo.badgeNumber = params.badgeNumber;
75        openFolderData.layoutInfo[i][index] = appInfo;
76        break;
77      }
78    }
79    Log.showDebug(TAG, `mLocalEventListener openFolderData: ${JSON.stringify(openFolderData)}`);
80    this.refreshFolder(openFolderData);
81  }
82
83  private constructor() {
84    super();
85    this.mBigFolderModel = BigFolderModel.getInstance();
86    this.mSettingsModel = SettingsModel.getInstance();
87    this.mPageDesktopModel = PageDesktopModel.getInstance();
88    this.mGridConfig = this.mSettingsModel.getGridConfig();
89    this.mPinyinSort = new PinyinSort();
90    this.mBigFolderModel.registerFolderUpdateEvent(this.mLocalEventListener);
91    this.mFolderStyleConfig = layoutConfigManager.getStyleConfig(BigFolderStyleConfig.APP_LIST_STYLE_CONFIG,
92      BigFolderConstants.FEATURE_NAME);
93    this.mFolderLayoutConfig = layoutConfigManager.getFunctionConfig(FolderLayoutConfig.FOLDER_GRID_LAYOUT_INFO);
94  }
95
96  static getInstance(): BigFolderViewModel {
97    if (globalThis.BigFolderViewModelInstance == null) {
98      globalThis.BigFolderViewModelInstance = new BigFolderViewModel();
99    }
100    return globalThis.BigFolderViewModelInstance;
101  }
102
103  /**
104   * return BigFolderStyleConfig
105   */
106  getFolderStyleConfig(): BigFolderStyleConfig {
107    return this.mFolderStyleConfig;
108  }
109
110  /**
111    * return folderOpenLayoutTable
112    */
113  getFolderLayoutConfig(): any {
114    return this.mFolderLayoutConfig.getFolderLayoutInfo().folderOpenLayoutTable;
115  }
116
117  /**
118   * add new folder
119   *
120   * @param {AppItemInfo[]} appLayoutInfo (two app for create new folder).
121   */
122  async addNewFolder(appLayoutInfo: AppItemInfo[]) {
123    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
124    const settingAppInfoList = this.mSettingsModel.getAppListInfo();
125    const folderAppInfo: AppItemInfo[] = [];
126    for (let j = 0; j < appLayoutInfo.length; j++) {
127      Log.showDebug(TAG, `addNewFolder appLayoutInfo: ${JSON.stringify(appLayoutInfo[j])}`)
128      for (let i = 0; i < settingAppInfoList.length; i++) {
129        if (settingAppInfoList[i].keyName === appLayoutInfo[j].keyName) {
130          folderAppInfo.push(settingAppInfoList[i]);
131          break;
132        }
133      }
134    }
135
136    // sum all app badgeNumber
137    let badgeNumber = 0;
138    for (let i = 0; i < folderAppInfo.length; i++) {
139      if (folderAppInfo[i].badgeNumber && folderAppInfo[i].badgeNumber > 0) {
140        badgeNumber = badgeNumber + folderAppInfo[i].badgeNumber;
141      }
142    }
143
144    // Delete {the app list} from desktop app list
145    for (let i = 0; i < appLayoutInfo.length; i++) {
146      const index = gridLayoutInfo.layoutInfo.indexOf(appLayoutInfo[i] as LauncherDragItemInfo);
147      if (index != CommonConstants.INVALID_VALUE) {
148        gridLayoutInfo.layoutInfo.splice(index, 1);
149      }
150    }
151
152    const folderInfo = await this.createNewFolderInfo();
153    folderInfo.layoutInfo.push(folderAppInfo);
154    folderInfo.badgeNumber = badgeNumber;
155
156    const needNewPage: boolean = this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfo, folderInfo);
157    if (needNewPage) {
158      gridLayoutInfo.layoutDescription.pageCount = gridLayoutInfo.layoutDescription.pageCount + 1;
159      for (let index = 0; index < gridLayoutInfo.layoutInfo.length; index++) {
160        if (gridLayoutInfo.layoutInfo[index].page > this.mPageDesktopModel.getPageIndex()) {
161          gridLayoutInfo.layoutInfo[index].page++;
162        }
163      }
164    }
165
166    // Push folder into the layoutInfo,include {the app list}
167    gridLayoutInfo.layoutInfo.push(folderInfo as LauncherDragItemInfo);
168    this.deleteAppLayoutItems(gridLayoutInfo, appLayoutInfo);
169    if (needNewPage) {
170      this.mPageDesktopModel.setPageIndex(this.mPageDesktopModel.getPageIndex() + 1);
171    }
172  }
173
174  /**
175   * add app to folder
176   *
177   * @param appInfo AppInfo
178   * @param folderId folderId
179   */
180  addOneAppToFolder(appInfo, folderId): void {
181    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
182    let appListInfo = this.mSettingsModel.getAppListInfo();
183    appListInfo = appListInfo.filter(item => item.keyName !== appInfo.keyName);
184    // add App
185    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
186      const layoutInfo = gridLayoutInfo.layoutInfo[i];
187      if (layoutInfo.typeId === CommonConstants.TYPE_FOLDER && layoutInfo.folderId === folderId) {
188        const info = layoutInfo.layoutInfo;
189        if (layoutInfo.badgeNumber && layoutInfo.badgeNumber > 0) {
190          if (appInfo.badgeNumber && appInfo.badgeNumber > 0) {
191            layoutInfo.badgeNumber = layoutInfo.badgeNumber + appInfo.badgeNumber;
192          }
193        } else {
194          layoutInfo.badgeNumber = appInfo.badgeNumber;
195        }
196        const lastPageItems = info[info.length - 1];
197        if (lastPageItems[lastPageItems.length - 1].typeId == CommonConstants.TYPE_ADD) {
198          lastPageItems[lastPageItems.length - 1] = appInfo;
199        } else {
200          const openFolderConfig = this.mBigFolderModel.getFolderOpenLayout();
201          if (lastPageItems.length == openFolderConfig.column * openFolderConfig.row) {
202            info.push([appInfo]);
203          } else {
204            lastPageItems.push(appInfo);
205          }
206        }
207        break;
208      }
209    }
210
211    // delete app from desktop
212    this.mSettingsModel.setAppListInfo(appListInfo);
213    this.deleteAppLayoutItems(gridLayoutInfo, [appInfo]);
214  }
215
216  /**
217 * delete apps in pageDesktop
218 * @param appListInfo
219 */
220  private deleteAppLayoutItems(gridLayoutInfo, appLayoutInfo) {
221    for (let i = 0; i < appLayoutInfo.length; i++) {
222      gridLayoutInfo.layoutInfo = gridLayoutInfo.layoutInfo.filter(item => item.keyName != appLayoutInfo[i].keyName);
223    }
224    Log.showDebug(TAG, `deleteAppItems gridLayoutInfo.layoutInfo: ${gridLayoutInfo.layoutInfo.length}`);
225    this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
226    localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
227  }
228
229  /**
230   * Delete app from folder by dragging
231   *
232   * @param {AppItemInfo[]} folderAppList.
233   * @param {number} index.
234   */
235  deleteAppByDraging(folderAppList: AppItemInfo[], index: number): boolean {
236    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
237    if (folderAppList.length == 0 || folderAppList.length <= index) {
238      return false;
239    }
240    const dragAppInfo = folderAppList[index];
241    if (folderAppList.length > 2) {
242      const needNewPage: boolean = this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfo, dragAppInfo);
243      Log.showDebug(TAG, `deleteAppByDraging needNewPage: ${needNewPage}`);
244      if (needNewPage) {
245        return false;
246      }
247    }
248
249    folderAppList.splice(index, 1);
250    if (folderAppList.length > 0 && folderAppList[folderAppList.length - 1].typeId == CommonConstants.TYPE_ADD) {
251      folderAppList.pop();
252    }
253    const folderLayoutInfo = this.filterFolderPage(folderAppList);
254    const openFolderData: FolderData = AppStorage.get('openFolderData');
255    const removeAppInfos = [dragAppInfo];
256    const folderIndex = gridLayoutInfo.layoutInfo.findIndex(item => {
257      return item.typeId === CommonConstants.TYPE_FOLDER && item.folderId === openFolderData.folderId;
258    });
259
260    if (folderLayoutInfo.length == 1 && folderLayoutInfo[0].length == 1) {
261      // delete folder and add app to desktop
262      removeAppInfos.push(folderLayoutInfo[0][0]);
263      gridLayoutInfo.layoutInfo.splice(folderIndex, 1);
264    } else {
265      this.updateBadgeNumber(gridLayoutInfo.layoutInfo[folderIndex], dragAppInfo);
266      openFolderData.layoutInfo = folderLayoutInfo;
267    }
268
269    const appListInfo = this.mSettingsModel.getAppListInfo();
270    for (let i = 0; i < removeAppInfos.length; i++) {
271      this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfo, removeAppInfos[i]);
272      const gridLayout = this.createAppLayoutInfo(removeAppInfos[i]);
273      gridLayoutInfo.layoutInfo.push(gridLayout as LauncherDragItemInfo);
274      appListInfo.push(removeAppInfos[i]);
275    }
276    this.mSettingsModel.setAppListInfo(appListInfo);
277    this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
278    return true;
279  }
280
281  /**
282   * create new app layoutInfo
283   *
284   * @param appInfo
285   */
286  private createAppLayoutInfo(appInfo: AppItemInfo): AppItemInfo {
287    const appLayout: AppItemInfo = new AppItemInfo();
288    appLayout.bundleName = appInfo.bundleName;
289    appLayout.abilityName = appInfo.abilityName;
290    appLayout.moduleName = appInfo.moduleName;
291    appLayout.keyName = appInfo.keyName;
292    appLayout.typeId = appInfo.typeId;
293    appLayout.area = appInfo.area;
294    appLayout.page = appInfo.page;
295    appLayout.column = appInfo.column;
296    appLayout.row = appInfo.row;
297    return appLayout;
298  }
299
300  /**
301   * update folder badgeNumber
302   *
303   * @param folderLayoutInfo
304   * @param dragAppInfo
305   */
306  private updateBadgeNumber(folderLayoutInfo, dragAppInfo): void {
307    let folderBadgeNumber = 0;
308    if (folderLayoutInfo.badgeNumber && folderLayoutInfo.badgeNumber > 0) {
309      folderBadgeNumber = folderLayoutInfo.badgeNumber;
310      if (dragAppInfo.badgeNumber && dragAppInfo.badgeNumber > 0) {
311        folderBadgeNumber = folderBadgeNumber - dragAppInfo.badgeNumber;
312      }
313    }
314    folderLayoutInfo.badgeNumber = folderBadgeNumber;
315  }
316
317  /**
318   * Delete app from open folder
319   *
320   * @param {AppItemInfo} appInfo.
321   */
322  deleteAppFromOpenFolder(appInfo: AppItemInfo): FolderData {
323    let openFolderData: FolderData = AppStorage.get('openFolderData');
324    const folderLayoutInfo = this.getFolderLayoutInfo(openFolderData, appInfo);
325
326    // Delete app from the folder
327    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
328    const folderIndex = gridLayoutInfo.layoutInfo.findIndex(item => {
329      return item.typeId === CommonConstants.TYPE_FOLDER && item.folderId === openFolderData.folderId;
330    });
331
332    const appListInfo = this.mSettingsModel.getAppListInfo();
333    if (folderLayoutInfo.length == 1 && folderLayoutInfo[0].length == 1) {
334      // delete from folder and add app to desktop
335      const appLayout = {
336        bundleName: folderLayoutInfo[0][0].bundleName,
337        abilityName: folderLayoutInfo[0][0].abilityName,
338        moduleName: folderLayoutInfo[0][0].moduleName,
339        keyName: folderLayoutInfo[0][0].keyName,
340        typeId: folderLayoutInfo[0][0].typeId,
341        area: folderLayoutInfo[0][0].area,
342        page: gridLayoutInfo.layoutInfo[folderIndex].page,
343        column: gridLayoutInfo.layoutInfo[folderIndex].column,
344        row: gridLayoutInfo.layoutInfo[folderIndex].row
345      };
346      gridLayoutInfo.layoutInfo.push(appLayout as LauncherDragItemInfo);
347      appListInfo.push(folderLayoutInfo[0][0]);
348      gridLayoutInfo.layoutInfo.splice(folderIndex, 1);
349      openFolderData = {
350        folderId: '',folderName: '', enterEditing: false, layoutInfo: []
351      };
352    } else {
353      this.updateBadgeNumber(gridLayoutInfo.layoutInfo[folderIndex], appInfo);
354      openFolderData.layoutInfo = folderLayoutInfo;
355    }
356    this.mSettingsModel.setAppListInfo(appListInfo);
357    this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
358    return openFolderData;
359  }
360
361  /**
362   * update folder app list info
363   *
364   * @param {AppItemInfo[]} appInfos.
365   * @param {FolderData} folderItem.
366   */
367  async updateFolderAppList(appInfos: AppItemInfo[], folderItem: FolderData): Promise<void> {
368    Log.showDebug(TAG, 'updateFolderAppList start');
369    let removeFolderApp: AppItemInfo[] = [];
370    let gridLayoutInfoTemp: GridLayoutInfo;
371    let gridLayoutInfo = {
372      layoutInfo: []
373    };
374    gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
375    gridLayoutInfoTemp = this.mSettingsModel.getLayoutInfo();
376    removeFolderApp = this.layoutInfoToList(folderItem);
377    // checked app <= 1
378    if (appInfos.length <= CommonConstants.FOLDER_APP_VALUE) {
379      for (let i = 0; i < gridLayoutInfoTemp.layoutInfo.length; i++) {
380        if (gridLayoutInfoTemp.layoutInfo[i].folderId === folderItem.folderId) {
381          gridLayoutInfoTemp.layoutInfo.splice(i, 1);
382          break;
383        }
384      }
385      folderItem.layoutInfo = [[]];
386      for (let i = 0; i < removeFolderApp.length; i++) {
387        localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD, removeFolderApp[i]);
388        this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfoTemp, removeFolderApp[i]);
389        const gridLayout = this.createAppLayoutInfo(removeFolderApp[i]);
390        gridLayoutInfoTemp.layoutInfo.push(gridLayout as LauncherDragItemInfo);
391      }
392      this.mSettingsModel.setLayoutInfo(gridLayoutInfoTemp);
393    } else {
394      // checked app's count >= 2
395      // update badgeNumber of folder
396      this.updateFolderBadgeNumber(appInfos, folderItem, gridLayoutInfo, gridLayoutInfoTemp);
397      // move app from other folder
398      this.moveAppFromOtherFolders(appInfos, folderItem, gridLayoutInfo, gridLayoutInfoTemp);
399      // move apps from desktop to folder
400      this.moveAppFromDesktopToFolder(appInfos, gridLayoutInfo, gridLayoutInfoTemp);
401      // move apps from folder to desktop
402      this.moveAppFromFolderToDesktop(appInfos, removeFolderApp, gridLayoutInfoTemp);
403      // delete blank page
404      this.deleteBlankPage();
405    }
406    Log.showDebug(TAG, 'updateFolderAppList end');
407  }
408
409  /**
410   * delete blank page
411   */
412  private deleteBlankPage(): void {
413    const layoutInfo = this.mSettingsModel.getLayoutInfo();
414    const pageItemMap = new Map<string, number>();
415    for (let i = 0; i < layoutInfo.layoutDescription.pageCount; i++) {
416      pageItemMap.set(i.toString(), 0);
417    }
418
419    for (let i = 0; i < layoutInfo.layoutInfo.length; i++) {
420      const tmpPage = layoutInfo.layoutInfo[i].page.toString();
421      pageItemMap.set(tmpPage, pageItemMap.get(tmpPage) + 1);
422    }
423
424    const blankPages = [];
425    for (let [page, count] of pageItemMap) {
426      if (count === 0) {
427        layoutInfo.layoutDescription.pageCount--;
428        blankPages.push(page);
429      }
430    }
431    for (let m = 0; m < layoutInfo.layoutInfo.length; m++) {
432      let pageMinus = 0;
433      for (let n = 0; n < blankPages.length; n++) {
434        if (layoutInfo.layoutInfo[m].page > blankPages[n]) {
435          pageMinus++;
436        }
437      }
438      if (pageMinus != 0) {
439        layoutInfo.layoutInfo[m].page = layoutInfo.layoutInfo[m].page - pageMinus;
440      }
441    }
442    this.mSettingsModel.setLayoutInfo(layoutInfo);
443    localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
444  }
445
446  /**
447   * get apps in checked appinfos, not in folderAppList
448   *
449   * @param appInfos
450   * @param folderAppList
451   */
452  getAppRemainInOtherFolder(appInfos: AppItemInfo[], folderAppList: AppItemInfo[]): AppItemInfo[] {
453    const appInfosRemaining = [];
454    for (let m = 0; m < folderAppList.length; m++) {
455      const appIndex = appInfos.findIndex(item => {
456        return item.keyName === folderAppList[m].keyName;
457      });
458      if (appIndex == CommonConstants.INVALID_VALUE) {
459        appInfosRemaining.push(folderAppList[m]);
460      }
461    }
462    return appInfosRemaining;
463  }
464
465  /**
466   * update badgeNumber of folder
467   *
468   * @param appInfos
469   * @param folderItem
470   * @param gridLayoutInfo
471   */
472  private updateFolderBadgeNumber(appInfos: AppItemInfo[], folderItem: FolderData, gridLayoutInfo, gridLayoutInfoTemp): void {
473    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
474      if (gridLayoutInfo.layoutInfo[i].typeId === CommonConstants.TYPE_FOLDER
475      && gridLayoutInfo.layoutInfo[i].folderId === folderItem.folderId) {
476        let badgeNumber = 0;
477        appInfos.forEach((item) => {
478          if (item.badgeNumber && item.badgeNumber > 0) {
479            badgeNumber = badgeNumber + item.badgeNumber;
480          }
481        });
482        const folderLayoutInfo = this.filterFolderPage(appInfos);
483        folderItem.layoutInfo = folderLayoutInfo;
484        folderItem.badgeNumber = badgeNumber;
485        gridLayoutInfoTemp.layoutInfo[i].layoutInfo = JSON.parse(JSON.stringify(folderLayoutInfo));
486        this.mSettingsModel.setLayoutInfo(gridLayoutInfoTemp);
487        localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
488        break;
489      }
490    }
491  }
492
493  /**
494   * move app from other folders to folder or to desktop
495   *
496   * @param appInfos
497   * @param gridLayoutInfo
498   * @param gridLayoutInfoTemp
499   */
500  private moveAppFromOtherFolders(appInfos, folderItem, gridLayoutInfo, gridLayoutInfoTemp): void {
501    for (let i = gridLayoutInfo.layoutInfo.length - 1; i >= 0; i--) {
502      if (gridLayoutInfo.layoutInfo[i].typeId === CommonConstants.TYPE_FOLDER
503      && gridLayoutInfo.layoutInfo[i].folderId !== folderItem.folderId) {
504        const folderAppList = this.layoutInfoToList(gridLayoutInfo.layoutInfo[i]);
505        const appInfosRemaining = this.getAppRemainInOtherFolder(appInfos, folderAppList);
506        const thisFolderItemIndex = gridLayoutInfoTemp.layoutInfo.findIndex(item => {
507          return item.folderId === gridLayoutInfo.layoutInfo[i].folderId;
508        });
509
510        if (appInfosRemaining.length === 0) {
511          gridLayoutInfoTemp.layoutInfo.splice(thisFolderItemIndex, 1);
512          this.mSettingsModel.setLayoutInfo(gridLayoutInfoTemp);
513          localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
514        } else if (appInfosRemaining.length === CommonConstants.FOLDER_APP_VALUE) {
515          gridLayoutInfoTemp.layoutInfo.splice(thisFolderItemIndex, 1);
516          this.mSettingsModel.setLayoutInfo(gridLayoutInfoTemp);
517          localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD, appInfosRemaining[0]);
518        } else {
519          let badgeNumber = 0;
520          appInfosRemaining.forEach((item) => {
521            if (item.badgeNumber && item.badgeNumber > 0) {
522              badgeNumber = badgeNumber + item.badgeNumber;
523            }
524          });
525          gridLayoutInfoTemp.layoutInfo[thisFolderItemIndex].badgeNumber = badgeNumber;
526          gridLayoutInfoTemp.layoutInfo[thisFolderItemIndex].layoutInfo = this.filterFolderPage(appInfosRemaining);
527          this.mSettingsModel.setLayoutInfo(gridLayoutInfoTemp);
528          localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
529        }
530      }
531    }
532  }
533
534  /**
535   * move apps from desktop to folder
536   *
537   * @param appInfos
538   * @param gridLayoutInfo
539   * @param gridLayoutInfoTemp
540   */
541  private moveAppFromDesktopToFolder(appInfos, gridLayoutInfo, gridLayoutInfoTemp): void {
542    const appDesktopToFolder = [];
543    for (let i = 0; i < appInfos.length; i++) {
544      for (let j = 0; j < gridLayoutInfo.layoutInfo.length; j++) {
545        if (gridLayoutInfo.layoutInfo[j].typeId == CommonConstants.TYPE_APP &&
546        appInfos[i].keyName == gridLayoutInfo.layoutInfo[j].keyName) {
547          appDesktopToFolder.push(gridLayoutInfo.layoutInfo[j]);
548          break;
549        }
550      }
551    }
552
553    if (appDesktopToFolder.length > 0) {
554      this.deleteAppLayoutItems(gridLayoutInfoTemp, appDesktopToFolder);
555    }
556  }
557
558  /**
559   * move app from folder to desktop
560   *
561   * @param appInfos
562   * @param removeFolderApp
563   * @param gridLayoutInfoTemp
564   */
565  private moveAppFromFolderToDesktop(appInfos, removeFolderApp, gridLayoutInfoTemp) {
566    const appFolderToDesktop = [];
567    for (let i = 0; i < removeFolderApp.length; i++) {
568      let remainFlag = false;
569      for (let j = 0; j < appInfos.length; j++) {
570        if (appInfos[j].keyName == removeFolderApp[i].keyName) {
571          remainFlag = true;
572          break;
573        }
574      }
575      if (!remainFlag) {
576        appFolderToDesktop.push(removeFolderApp[i]);
577      }
578    }
579
580    if (appFolderToDesktop.length > 0) {
581      for (let i = 0; i < appFolderToDesktop.length; i++) {
582        const needNewPage: boolean = this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfoTemp, appFolderToDesktop[i]);
583        if (needNewPage) {
584          gridLayoutInfoTemp.layoutDescription.pageCount = gridLayoutInfoTemp.layoutDescription.pageCount + 1;
585          for (let index = 0; index < gridLayoutInfoTemp.layoutInfo.length; index++) {
586            if (gridLayoutInfoTemp.layoutInfo[index].page > this.mPageDesktopModel.getPageIndex()) {
587              gridLayoutInfoTemp.layoutInfo[index].page++;
588            }
589          }
590        }
591        const gridLayout = this.createAppLayoutInfo(appFolderToDesktop[i]);
592        gridLayoutInfoTemp.layoutInfo.push(gridLayout);
593        localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD, appFolderToDesktop[i]);
594      }
595      this.mSettingsModel.setLayoutInfo(gridLayoutInfoTemp);
596    }
597  }
598
599  /**
600   * get folder app list
601   *
602   * @param {array} folderId.
603   * @return {array} folderAppList.
604   */
605  async getFolderAppList(folderId) {
606    Log.showDebug(TAG, 'getFolderAppList start');
607    let folderAppList = [];
608    let gridLayoutInfo = {
609      layoutInfo: []
610    };
611    gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
612
613    // Get folder app list form the layout info
614    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
615      const layoutInfo = gridLayoutInfo.layoutInfo[i];
616      if (layoutInfo.typeId === CommonConstants.TYPE_FOLDER && layoutInfo.folderId === folderId) {
617        for (let j = 0; j < layoutInfo.layoutInfo.length; j++) {
618          folderAppList = folderAppList.concat(layoutInfo.layoutInfo[j]);
619        }
620      }
621    }
622    if (folderAppList.length > 0 && folderAppList[folderAppList.length - 1].typeId == CommonConstants.TYPE_ADD) {
623      folderAppList.pop();
624    }
625    AppStorage.setOrCreate('folderAppList', folderAppList);
626    return folderAppList;
627  }
628
629  /**
630   * get all folder list
631   *
632   * @return {array} folderList.
633   */
634  async getAllFolderList() {
635    Log.showDebug(TAG, 'getAllFolderList start');
636    const folderList = [];
637    let gridLayoutInfo = {
638      layoutInfo: []
639    };
640    gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
641
642    // Get folder list form the layout info
643    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
644      if (gridLayoutInfo.layoutInfo[i].typeId === CommonConstants.TYPE_FOLDER) {
645        folderList.push(gridLayoutInfo.layoutInfo[i]);
646      }
647    }
648    AppStorage.setOrCreate('allFolderList', folderList);
649    return folderList;
650  }
651
652  /**
653   * get the all app list for folder
654   *
655   * @param {number} folderId
656   *
657   */
658  async getFolderAddAppList(folderId: string): Promise<AppItemInfo[]> {
659    Log.showDebug(TAG, 'getFolderAddAppList start');
660    if (CheckEmptyUtils.checkStrIsEmpty(folderId)) {
661      Log.showDebug(TAG, 'getFolderAddAppList folderId is Empty');
662      return;
663    }
664    let allAppList: AppItemInfo[] = [];
665    let appInfos: AppItemInfo[] = [];
666    let gridLayoutInfo = {
667      layoutInfo: []
668    };
669    gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
670    const appListInfo = await this.mAppModel.getAppList();
671
672    // first push this current app
673    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
674      const layoutInfo = gridLayoutInfo.layoutInfo[i];
675      if (layoutInfo.typeId === CommonConstants.TYPE_FOLDER && layoutInfo.folderId === folderId) {
676        for (let j = 0; j < layoutInfo.layoutInfo.length; j++) {
677          appInfos = layoutInfo.layoutInfo[j];
678          for (let k = 0; k < appInfos.length; k++) {
679            appInfos[k].checked = true;
680            allAppList.push(appInfos[k]);
681          }
682        }
683        break;
684      }
685    }
686
687    if (allAppList.length > 0 && allAppList[allAppList.length - 1].typeId == CommonConstants.TYPE_ADD) {
688      allAppList.pop();
689    }
690
691    for (let i = 0; i < appListInfo.length; i++) {
692      let isExist = false;
693      for (let j = 0; j < allAppList.length; j++) {
694        if (appListInfo[i].keyName === allAppList[j].keyName) {
695          isExist = true;
696          break;
697        }
698      }
699      if (!isExist) {
700        appListInfo[i].checked = false;
701        allAppList.push(appListInfo[i]);
702      }
703    }
704    if (!this.getIsPad()) {
705      let bottomAppList: AppItemInfo[] = AppStorage.get('residentList') as AppItemInfo[];
706      if (!CheckEmptyUtils.isEmptyArr(bottomAppList)) {
707        for (let i = 0; i < bottomAppList.length; i++) {
708          allAppList = allAppList.filter((item) => {
709            if (bottomAppList[i].keyName == item.keyName) {
710              return false;
711            }
712            return true;
713          })
714        }
715      }
716    }
717    AppStorage.setOrCreate('allAppListForFolder', allAppList);
718    return allAppList;
719  }
720
721  /**
722   * open folder
723   *
724   * @param {FolderData} folderInfo.
725   */
726  addAddIcon(folderItem: FolderData): FolderData {
727    Log.showDebug(TAG, 'addAddIcon start');
728
729    if (folderItem.layoutInfo.length == 0) {
730      return folderItem;
731    }
732    const lastPageItem = folderItem.layoutInfo[folderItem.layoutInfo.length - 1];
733    if (lastPageItem[lastPageItem.length - 1].typeId === CommonConstants.TYPE_ADD) {
734      return folderItem;
735    }
736
737    const openFolderConfig = this.mBigFolderModel.getFolderOpenLayout();
738    const column = openFolderConfig.column;
739    const row = openFolderConfig.row;
740    const addInfo: AppItemInfo = new AppItemInfo();
741    addInfo.typeId = CommonConstants.TYPE_ADD;
742    addInfo.appName = '';
743    if (folderItem.layoutInfo[folderItem.layoutInfo.length - 1].length === column * row) {
744      folderItem.layoutInfo.push([addInfo]);
745    } else {
746      folderItem.layoutInfo[folderItem.layoutInfo.length - 1].push(addInfo);
747    }
748
749    Log.showDebug(TAG, 'addAddIcon end');
750    return folderItem;
751  }
752
753  /**
754   * open folder
755   *
756   * @param {FolderData} folderInfo.
757   */
758  delAddIcon(folderItem: FolderData): FolderData {
759    Log.showDebug(TAG, 'delAddIcon start');
760
761    if (folderItem.layoutInfo.length == 0) {
762      return folderItem;
763    }
764    const lastPageItem = folderItem.layoutInfo[folderItem.layoutInfo.length - 1];
765    if (lastPageItem[lastPageItem.length - 1].typeId !== CommonConstants.TYPE_ADD) {
766      return folderItem;
767    }
768    lastPageItem.pop();
769    if (lastPageItem.length == 0) {
770      folderItem.layoutInfo.pop();
771    } else {
772      folderItem.layoutInfo[folderItem.layoutInfo.length - 1] = lastPageItem;
773    }
774
775    Log.showDebug(TAG, 'delAddIcon end');
776    return folderItem;
777  }
778
779  /**
780   * open folder
781   *
782   * @param {boolean} isRename.
783   * @param {FolderData} folderItem.
784   */
785  async openFolder(isRename: boolean, folderItem: FolderData) {
786    Log.showDebug(TAG, 'openFolder start');
787    folderItem.enterEditing = isRename;
788
789    AppStorage.setOrCreate('openFolderData', folderItem);
790    this.mPageIndex = 0;
791    AppStorage.setOrCreate('openFolderPageIndex', this.mPageIndex);
792    AppStorage.setOrCreate('openFolderStatus', BigFolderConstants.OPEN_FOLDER_STATUS_OPEN);
793    Log.showDebug(TAG, 'openFolder end');
794  }
795
796  /**
797   * close folder
798   */
799  async closeFolder() {
800    Log.showDebug(TAG, 'closeFolder start');
801
802    this.mPageIndex = 0;
803    AppStorage.setOrCreate('openFolderPageIndex', this.mPageIndex);
804    AppStorage.setOrCreate('openFolderStatus', BigFolderConstants.OPEN_FOLDER_STATUS_CLOSE);
805  }
806
807  /**
808   * refresh folder data
809   *
810   * @param folderItem
811   */
812  async refreshFolder(folderItem: FolderData) {
813    Log.showDebug(TAG, 'refreshFolder start');
814    folderItem.enterEditing = false;
815    this.updateOpenFolderStatus(folderItem);
816    Log.showDebug(TAG, 'refreshFolder end');
817  }
818
819  /**
820   * get device type
821   *
822   * @return {boolean} isPad.
823   */
824  getIsPad(): boolean {
825    return CommonConstants.PAD_DEVICE_TYPE == AppStorage.get('deviceType');
826  }
827
828  /**
829   * modify folder name
830   *
831   * @param {FolderData} folderModel.
832   */
833  modifyFolderName(folderModel: FolderData): void {
834    let gridLayoutInfo: GridLayoutInfo = {
835      layoutDescription: undefined,
836      layoutInfo: []
837    };
838    gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
839
840    for (let i = 0; i < gridLayoutInfo.layoutInfo.length; i++) {
841      if (gridLayoutInfo.layoutInfo[i].typeId === CommonConstants.TYPE_FOLDER &&
842      gridLayoutInfo.layoutInfo[i].folderId === folderModel.folderId) {
843        gridLayoutInfo.layoutInfo[i].folderName = folderModel.folderName;
844      }
845    }
846    this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
847  }
848
849  /**
850   * make the applist into folder page
851   *
852   * @param appInfos
853   */
854  filterFolderPage(appInfos: AppItemInfo[]): AppItemInfo[][] {
855    const folderLayoutInfo = [];
856    const appListInfo = JSON.parse(JSON.stringify(appInfos));
857    const openFolderConfig = this.mBigFolderModel.getFolderOpenLayout();
858
859    const itemCountByPage = openFolderConfig.column * openFolderConfig.row;
860    let pageCount = Math.floor(appListInfo.length / itemCountByPage);
861    if (appListInfo.length % itemCountByPage != 0) {
862      pageCount = pageCount + 1;
863    }
864    Log.showDebug(TAG, `filterFolderPage pageCount: ${pageCount}`);
865    for (let i = 0; i < pageCount; i++) {
866      let pageInfo = [];
867      if (itemCountByPage > appListInfo.length) {
868        pageInfo = appListInfo.splice(0, appListInfo.length);
869      } else {
870        pageInfo = appListInfo.splice(0, itemCountByPage);
871      }
872      folderLayoutInfo.push(pageInfo);
873    }
874    return folderLayoutInfo;
875  }
876
877  /**
878   * make the folder layoutInfo into list
879   *
880   * @param {FolderData} folderInfo
881   */
882  private layoutInfoToList(folderInfo: FolderData): AppItemInfo[] {
883    let appInfo: AppItemInfo[] = [];
884    for (let i = 0; i < folderInfo.layoutInfo.length; i++) {
885      for (let j = 0; j < folderInfo.layoutInfo[i].length; j++) {
886        if (folderInfo.layoutInfo[i][j].typeId != CommonConstants.TYPE_ADD) {
887          appInfo = appInfo.concat(folderInfo.layoutInfo[i][j]);
888        }
889      }
890    }
891    return appInfo;
892  }
893
894  /**
895   * create folder info
896   *
897   * @return {LauncherDragItemInfo} folderInfo.
898   */
899  private async createNewFolderInfo() {
900    const folderConfig = this.mBigFolderModel.getFolderLayout();
901    const folderName = await this.generateFolderName();
902    // Create new folder info
903    const folderInfo = {
904      folderId: this.getUUID(),
905      folderName: folderName,
906      layoutInfo: [],
907      typeId: CommonConstants.TYPE_FOLDER,
908      area: folderConfig.area,
909      badgeNumber: 0
910    };
911    return folderInfo as LauncherDragItemInfo;
912  }
913
914  /**
915   * generate folder name
916   *
917   * @return {string} folderName.
918   */
919  private async generateFolderName() {
920    Log.showDebug(TAG, 'generateFolderName start');
921    const folderList = await this.getAllFolderList();
922    let folderName: string = await ResourceManager.getInstance().getStringByIdSync($r('app.string.new_folder_name').id);
923    const autoNameFolderList = folderList.filter((element, index, self) => {
924      return element.folderName.startsWith(folderName) && (element.folderName.length > folderName.length);
925    });
926
927    autoNameFolderList.sort(this.mPinyinSort.sortByFolderName.bind(this.mPinyinSort));
928
929    let nameNumber = 1;
930    let tempFolderName = folderName + nameNumber;
931    for (let i = 0; i < autoNameFolderList.length; i++) {
932      if (autoNameFolderList[i].folderName == tempFolderName) {
933        nameNumber = nameNumber + 1;
934        tempFolderName = folderName + nameNumber;
935      } else {
936        break;
937      }
938    }
939    folderName = folderName + nameNumber;
940    return folderName;
941  }
942
943  /**
944   * generate a non duplicate ID
945   *
946   * @param {string} idLength
947   */
948  private getUUID(): string {
949    Log.showDebug(TAG, 'getUUID start');
950    let id = Date.now().toString(this.HEXADECIMAL_VALUE);
951    id += Math.random().toString(this.HEXADECIMAL_VALUE).substr(2);
952    return id;
953  }
954
955  /**
956   * change the open folder page number.
957   *
958   * @param idx: Page number
959   */
960  changeIndex(idx): void {
961    this.mPageIndex = idx;
962    AppStorage.setOrCreate('openFolderPageIndex', this.mPageIndex);
963  }
964
965  /**
966   * get the open folder page number.
967   */
968  getIndex(): number {
969    return this.mPageIndex;
970  }
971
972  /**
973   * get addlist dialog's column
974   */
975  getAddListColumn(): number {
976    return this.mBigFolderModel.getFolderAddAppLayout().column;
977  }
978
979  /**
980   * get add app dialog's height
981   *
982   * @param appList
983   */
984  getDialogHeight(appList: AppItemInfo[]): number {
985    let height = 0;
986    const styleConfig = this.mFolderStyleConfig;
987    const column = this.mBigFolderModel.getFolderAddAppLayout().column;
988    const row = this.mBigFolderModel.getFolderAddAppLayout().row;
989    const num = Math.ceil(appList.length / column);
990    if (num <= row) {
991      height = styleConfig.mAddFolderDialogHeight;
992    } else {
993      const gridHeight = num * (this.mFolderStyleConfig.mAddFolderIconSize + this.mFolderStyleConfig.mAddFolderTextLines) + num * styleConfig.mAddFolderGridGap +
994      styleConfig.mAddFolderGridMargin * 2;
995      height = gridHeight + BigFolderStyleConstants.DEFAULT_APP_ADD_TITLE_SIZE +
996      BigFolderStyleConstants.DEFAULT_BUTTON_HEIGHT + BigFolderStyleConstants.DEFAULT_DIALOG_BOTTOM_MARGIN;
997      if (height > styleConfig.mAddFolderMaxHeight) {
998        height = styleConfig.mAddFolderMaxHeight;
999      }
1000    }
1001    return height;
1002  }
1003
1004  /**
1005   * delete app from folder
1006   *
1007   * @param bundleName
1008   */
1009  deleteAppFromFolderByUninstall(bundleName): void {
1010    Log.showDebug(TAG, 'deleteAppFromFolderByUninstall start');
1011    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
1012    const layoutInfo = gridLayoutInfo.layoutInfo;
1013    for (let i = 0; i < layoutInfo.length; i++) {
1014      if (layoutInfo[i].typeId == CommonConstants.TYPE_FOLDER) {
1015        let folderAppList = this.layoutInfoToList(layoutInfo[i] as FolderData);
1016        folderAppList = folderAppList.filter(item => item.bundleName != bundleName);
1017        this.updateFolderInfo(folderAppList, gridLayoutInfo, i);
1018      }
1019    }
1020    Log.showDebug(TAG, 'deleteAppFromFolderByUninstall end');
1021  }
1022
1023  /**
1024   * update layoutInfo when only one item in the folder
1025   *
1026   * @param folderAppList
1027   * @param gridLayoutInfo
1028   * @param index
1029   */
1030  private updateFolderInfo(folderAppList, gridLayoutInfo, index): void {
1031    if (folderAppList.length == 0) {
1032      gridLayoutInfo.layoutInfo.splice(index, 1);
1033      this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
1034      localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
1035    } else if (folderAppList.length == 1) {
1036      const appLayoutInfo = {
1037        bundleName: folderAppList[0].bundleName,
1038        abilityName: folderAppList[0].abilityName,
1039        moduleName: folderAppList[0].moduleName,
1040        keyName: folderAppList[0].keyName,
1041        typeId: CommonConstants.TYPE_APP,
1042        area: [1, 1],
1043        page: gridLayoutInfo.layoutInfo[index].page,
1044        column: gridLayoutInfo.layoutInfo[index].column,
1045        row: gridLayoutInfo.layoutInfo[index].row
1046      };
1047      gridLayoutInfo.layoutInfo.splice(index, 1);
1048      gridLayoutInfo.layoutInfo.push(appLayoutInfo);
1049      this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
1050      localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD, folderAppList[0]);
1051    } else {
1052      gridLayoutInfo.layoutInfo[index].layoutInfo = this.filterFolderPage(folderAppList);
1053      this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
1054      localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
1055    }
1056  }
1057
1058  /**
1059   * remove app from folder
1060   *
1061   * @param {AppItemInfo} appInfo.
1062   */
1063  removeAppOutOfFolder(appInfo: AppItemInfo): void {
1064    let openFolderData: FolderData = AppStorage.get('openFolderData');
1065
1066    const folderAppList = this.getAppListInFolder(openFolderData);
1067    this.deleteAppFromFolderAppList(appInfo, folderAppList);
1068    const folderLayoutInfo = this.filterFolderPage(folderAppList);
1069
1070    const removeAppInfos = [appInfo];
1071    const gridLayoutInfo = this.mSettingsModel.getLayoutInfo();
1072    const folderIndex = gridLayoutInfo.layoutInfo.findIndex(item => {
1073      return item.typeId === CommonConstants.TYPE_FOLDER && item.folderId === openFolderData.folderId;
1074    });
1075
1076    if (folderLayoutInfo.length == 1 && folderLayoutInfo[0].length == 1) {
1077      // delete folder and add app to desktop
1078      removeAppInfos.push(folderLayoutInfo[0][0]);
1079      gridLayoutInfo.layoutInfo.splice(folderIndex, 1);
1080      openFolderData = {
1081        folderId: '',enterEditing: false, folderName: '', layoutInfo: []
1082      };
1083    } else {
1084      this.updateBadgeNumber(gridLayoutInfo.layoutInfo[folderIndex], appInfo);
1085      openFolderData.layoutInfo = folderLayoutInfo;
1086    }
1087    const appListInfo = this.mSettingsModel.getAppListInfo();
1088    // Add app to desktop app list
1089    for (let i = 0; i < removeAppInfos.length; i++) {
1090      const needNewPage: boolean = this.mPageDesktopModel.updatePageDesktopLayoutInfo(gridLayoutInfo, removeAppInfos[i]);
1091      if (needNewPage) {
1092        gridLayoutInfo.layoutDescription.pageCount = gridLayoutInfo.layoutDescription.pageCount + 1;
1093        for (let index = 0; index < gridLayoutInfo.layoutInfo.length; index++) {
1094          if (gridLayoutInfo.layoutInfo[index].page > this.mPageDesktopModel.getPageIndex()) {
1095            gridLayoutInfo.layoutInfo[index].page++;
1096          }
1097        }
1098      }
1099      const gridLayout = this.createAppLayoutInfo(removeAppInfos[i]);
1100      gridLayoutInfo.layoutInfo.push(gridLayout as LauncherDragItemInfo);
1101      const appIndex = appListInfo.findIndex(item => {
1102        return item.keyName === removeAppInfos[i].keyName;
1103      })
1104      if (appIndex == CommonConstants.INVALID_VALUE) {
1105        appListInfo.push(removeAppInfos[i]);
1106      }
1107    }
1108    this.mSettingsModel.setAppListInfo(appListInfo);
1109    this.mSettingsModel.setLayoutInfo(gridLayoutInfo);
1110    localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE, null);
1111    this.updateOpenFolderStatus(openFolderData);
1112  }
1113
1114  /**
1115   * update folderData and openFolderStatus
1116   *
1117   * @param openFolderData
1118   */
1119  private updateOpenFolderStatus(openFolderData: FolderData): void {
1120    AppStorage.setOrCreate('openFolderData', openFolderData);
1121    if (openFolderData.folderId == '') {
1122      AppStorage.setOrCreate('openFolderStatus', BigFolderConstants.OPEN_FOLDER_STATUS_CLOSE);
1123    } else {
1124      AppStorage.setOrCreate('openFolderStatus', BigFolderConstants.OPEN_FOLDER_STATUS_REFRESH);
1125    }
1126  }
1127
1128  /**
1129   * delete appInfo from folder
1130   *
1131   * @param appInfo
1132   * @param folderAppList
1133   */
1134  private deleteAppFromFolderAppList(appInfo, folderAppList): void {
1135    const appIndex = folderAppList.findIndex(item => {
1136      return item.keyName === appInfo.keyName;
1137    });
1138    if (appIndex !== CommonConstants.INVALID_VALUE) {
1139      folderAppList.splice(appIndex, 1);
1140    }
1141  }
1142
1143  /**
1144   * get folder's appList from appStorage
1145   *
1146   * @param openFolderData
1147   */
1148  private getAppListInFolder(openFolderData: FolderData): AppItemInfo[] {
1149    let folderAppList = [];
1150    for (let i = 0; i < openFolderData.layoutInfo.length; i++) {
1151      folderAppList = folderAppList.concat(openFolderData.layoutInfo[i]);
1152    }
1153    if (folderAppList.length > 0 && folderAppList[folderAppList.length - 1].typeId === CommonConstants.TYPE_ADD) {
1154      folderAppList.pop();
1155    }
1156    return folderAppList;
1157  }
1158
1159  /**
1160   * get folder layoutInfo after delete appInfo from folder
1161   *
1162   * @param openFolderData
1163   * @param appInfo
1164   */
1165  private getFolderLayoutInfo(openFolderData: FolderData, appInfo: AppItemInfo): AppItemInfo[][] {
1166    let folderAppList = this.getAppListInFolder(openFolderData);
1167    const index = folderAppList.findIndex(item => {
1168      return item.keyName === appInfo.keyName;
1169    });
1170    if (index !== CommonConstants.INVALID_VALUE) {
1171      folderAppList.splice(index, 1);
1172    }
1173    return this.filterFolderPage(folderAppList);
1174  }
1175}