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