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