• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import {
17  AppMenu,
18  FormManagerDialog,
19} from '@ohos/common/component'
20import {
21  CommonConstants,
22  StyleConstants,
23  LayoutViewModel,
24  CardItemInfo,
25  FormModel,
26  Log,
27  SettingsModel,
28  windowManager,
29  AppItemInfo,
30  ResourceManager,
31  MenuInfo,
32  AppModel,
33  localEventManager,
34  EventConstants
35} from '@ohos/common';
36import ServiceFormAppItem from '../common/uicomponents/ServiceFormAppItem';
37import ServiceFormItem from '../common/uicomponents/ServiceFormItem';
38import ThisStyleConstants from '../common/constants/StyleConstants';
39import GridRowUtils from '../manager/GridRowManager';
40import ServiceFormManager from '../manager/ServiceFormManager';
41import { PageDesktopViewModel } from '../../../../../../pagedesktop/src/main/ets/default/viewmodel/PageDesktopViewModel';
42
43const TAG = 'FormServiceComponent';
44
45/**
46 * Form service view Component (phone adaptation).
47 */
48@Component
49export struct FormServiceComponent {
50  @StorageLink('screenWidth') @Watch('initPage') screenWidth: number = 0;
51  @StorageLink('screenHeight') screenHeight: number = 0;
52  @State formAppInfos: AppItemInfo[] = [];
53  @State showFormInfos: CardItemInfo[] = new Array();
54  private readonly mServiceFormManager: ServiceFormManager = ServiceFormManager.getInstance();
55  private mFormModel: FormModel = FormModel.getInstance();
56  private mAppModel: AppModel = AppModel.getInstance();
57  private clickedformApp: AppItemInfo = new AppItemInfo();
58  private clearForm: Function = () => {};
59  private gridRowUtils: GridRowUtils = new GridRowUtils(0, 0, 0);
60  private formServiceWidth: number = 0;
61  private titleBarWidth: number = 0;
62  private sysUITopHeight: number = 0;
63  private sysUIBottomHeight: number = 0;
64  private scrollerWrapHeight: number = 0;
65  private scroller: Scroller = new Scroller();
66  @StorageProp('cornerRadiusDefaultL') cornerRadiusDefaultL: number = px2vp(ResourceManager.getInstance()
67    .getNumberByResource($r('sys.float.ohos_id_corner_radius_default_l')));
68
69  private async initServiceFormInfo(): Promise<void> {
70    // 从包管理获取app
71    this.formAppInfos = await this.mServiceFormManager.getServiceFormAppList();
72    Log.showInfo(TAG, `has ${this.formAppInfos.length} apps with form`);
73
74    // 获取推荐卡片
75    let recommendForms: CardItemInfo[] = await this.mServiceFormManager.getServiceForm();
76    Log.showInfo(TAG, `recommendCardsDataPool has ${recommendForms.length} cards`);
77    // 卡片信息补全
78    this.mServiceFormManager.formInfoComplete(recommendForms, this.formAppInfos);
79    // 获取展示卡片
80    this.showFormInfos = this.mServiceFormManager.getShowFormInfos(recommendForms);
81    Log.showInfo(TAG, `this.showFormInfos has ${this.showFormInfos.length} cards`);
82  }
83
84  private onAppStateChanged = () => {
85    // 推荐卡片更新后需要重新获取推荐列表
86    this.initServiceFormInfo();
87  }
88  private readonly listener = this.onAppStateChanged;
89
90  /**
91   * 返回箭头
92   */
93  private backToDeskTop(): void {
94    windowManager.destroyWindow(windowManager.FORM_SERVICE_WINDOW_NAME);
95  }
96
97  aboutToAppear(): void {
98    this.sysUITopHeight = LayoutViewModel.getInstance().getSysUITopHeight();
99    this.sysUIBottomHeight = LayoutViewModel.getInstance().getSysUIBottomHeight();
100    Log.showDebug(TAG, `sysUITopHeight:${this.sysUITopHeight},sysUIBottomHeight:${this.sysUIBottomHeight}`);
101    this.scrollerWrapHeight = this.screenHeight - ThisStyleConstants.FORM_SERVICE_BAR_HEIGHT - this.sysUITopHeight
102      - this.sysUIBottomHeight;
103    this.initPage();
104    this.mAppModel.registerStateChangeListener(this.listener);
105    this.onAppStateChanged();
106  }
107
108  aboutToDisappear(): void {
109    this.formManagerDialogController = null;
110    this.mAppModel.unregisterAppStateChangeListener(this.listener);
111  }
112
113  initPage(): void {
114    this.titleBarWidth = this.screenWidth - 2 * ThisStyleConstants.FORM_SERVICE_MARGIN_HORIZONTAL;
115    if (this.screenWidth < 520) {
116      this.formServiceWidth = this.titleBarWidth;
117      this.gridRowUtils = new GridRowUtils(ThisStyleConstants.FORM_SERVICE_GRID_ROW_COLUMNS,
118        ThisStyleConstants.FORM_SERVICE_GRID_ROW_GUTTER_X, this.formServiceWidth);
119    } else if (this.screenWidth < 840) {
120      let gridRowUtilsTemp: GridRowUtils = new GridRowUtils(ThisStyleConstants.FORM_SERVICE_GRID_ROW_COLUMNS * 2,
121        ThisStyleConstants.FORM_SERVICE_GRID_ROW_GUTTER_X, this.titleBarWidth);
122      this.formServiceWidth = this.titleBarWidth - (gridRowUtilsTemp.getSingleColumnWidth() +
123      gridRowUtilsTemp.getGutterX()) * 2;
124      this.gridRowUtils = new GridRowUtils(gridRowUtilsTemp.getColumns() - 2, gridRowUtilsTemp.getGutterX(),
125        this.formServiceWidth);
126    } else {
127      let gridRowUtilsTemp: GridRowUtils = new GridRowUtils(ThisStyleConstants.FORM_SERVICE_GRID_ROW_COLUMNS * 3,
128        ThisStyleConstants.FORM_SERVICE_GRID_ROW_GUTTER_X, this.titleBarWidth);
129      this.formServiceWidth = this.titleBarWidth - (gridRowUtilsTemp.getSingleColumnWidth() +
130      gridRowUtilsTemp.getGutterX()) * 2;
131      this.gridRowUtils = new GridRowUtils(gridRowUtilsTemp.getColumns() - 2, gridRowUtilsTemp.getGutterX(),
132        this.formServiceWidth);
133    }
134  }
135
136  formClick(event: ClickEvent, formItem: CardItemInfo): void {
137    let clickedFormAppInfos: AppItemInfo[] = this.formAppInfos.filter(info => info.bundleName == formItem.bundleName);
138    if (clickedFormAppInfos.length == 0) {
139      Log.showError(TAG, `The clicked card has no app information.`);
140      return;
141    }
142    let formAppInfo: AppItemInfo = clickedFormAppInfos[0];
143    if (SettingsModel.getInstance().getDevice() == CommonConstants.DEFAULT_DEVICE_TYPE) {
144      this.mFormModel.doBeforeJumpToFormManager(formAppInfo.bundleName).then(() => {
145        AppStorage.setOrCreate('formAppInfo', formAppInfo);
146        windowManager.createWindowWithName(windowManager.FORM_MANAGER_WINDOW_NAME, windowManager.RECENT_RANK);
147      })
148    } else {
149      this.clickedformApp = JSON.parse(JSON.stringify(formAppInfo));
150      this.formManagerDialogController?.open();
151    }
152  }
153
154  formManagerDialogController: CustomDialogController | null = new CustomDialogController({
155    builder: FormManagerDialog({
156      cancel: (callback?: () => void) => {
157        // delete all form
158        if (callback !== undefined) {
159          this.clearForm = callback;
160        } else {
161          Log.showError(TAG, `FormManagerDialog callback error`); // 维测日志
162        }
163      },
164      confirm: (formCardItem: CardItemInfo) => {
165        PageDesktopViewModel.getInstance().createCardToDeskTop(formCardItem);
166      },
167      bundleName: this.clickedformApp.bundleName as string,
168      appName: this.clickedformApp.appName as string,
169      appLabelId: this.clickedformApp.appLabelId as number
170    }),
171    cancel: this.cancelFormDialog,
172    autoCancel: true,
173    customStyle: true
174  });
175
176  /**
177   * When click cancel dialog, this function will be called.
178   */
179  cancelFormDialog(): void {
180    this.clearForm();
181  }
182
183  formAppClick = (event: ClickEvent, appItem: AppItemInfo): void => {
184    if (SettingsModel.getInstance().getDevice() == CommonConstants.DEFAULT_DEVICE_TYPE) {
185      this.mFormModel.doBeforeJumpToFormManager(appItem.bundleName).then(() => {
186        AppStorage.setOrCreate('formAppInfo', appItem);
187        windowManager.createWindowWithName(windowManager.FORM_MANAGER_WINDOW_NAME, windowManager.RECENT_RANK);
188      })
189    } else {
190      this.clickedformApp = appItem;
191      this.formManagerDialogController?.open();
192    }
193  }
194
195  private getFormWidth(dimension?: number): number {
196    if (dimension == CommonConstants.CARD_DIMENSION_2x4) {
197      return this.gridRowUtils.getSpanWidth(4);
198    }
199    if (dimension == CommonConstants.CARD_DIMENSION_2x2) {
200      return this.gridRowUtils.getSpanWidth(2);
201    }
202    return 0;
203  }
204
205  private getFormHeight(dimension?: number): number {
206    if (dimension == CommonConstants.CARD_DIMENSION_2x4
207      || dimension == CommonConstants.CARD_DIMENSION_2x2) {
208      return this.gridRowUtils.getSpanWidth(2);
209    }
210    return 0;
211  }
212
213  @Builder FormMenuBuilder(formItem: CardItemInfo) {
214    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
215      AppMenu({
216        menuInfoList: this.createAddFormToDesktopMenuInfo(formItem)
217      })
218    }
219  }
220
221  /**
222   * 添加卡片至桌面
223   *
224   * @param formInfo 卡片信息
225   */
226  private createAddFormToDesktopMenuInfo(formItem: CardItemInfo): MenuInfo[] {
227    let menuInfoList: MenuInfo[] = new Array<MenuInfo>();
228    let addFormToDesktopMenuInfo: MenuInfo = new MenuInfo();
229    addFormToDesktopMenuInfo.menuType = CommonConstants.MENU_TYPE_FIXED;
230    addFormToDesktopMenuInfo.menuImgSrc = '/common/pics/ic_form_addToDesktop.svg';
231    addFormToDesktopMenuInfo.menuText = $r('app.string.add_to_desktop');
232    addFormToDesktopMenuInfo.onMenuClick = (): void => {
233      localEventManager.sendLocalEventSticky(EventConstants.EVENT_OPEN_FOLDER_TO_CLOSE, null);
234      let formInfo: CardItemInfo = this.getChoosedCard(formItem);
235      PageDesktopViewModel.getInstance().createCardToDeskTop(formInfo);
236      this.backToDeskTop();
237    };
238    menuInfoList.push(addFormToDesktopMenuInfo);
239    return menuInfoList;
240  }
241
242  private getChoosedCard(choosedItem: CardItemInfo): CardItemInfo {
243    let formItem = choosedItem;
244    formItem.cardId = choosedItem.cardId;
245    formItem.cardName = choosedItem.cardName;
246    formItem.cardDimension = choosedItem.cardDimension;
247    formItem.dragLayerWidth = this.getFormWidth(formItem.cardDimension) * 1.05;
248    formItem.dragLayerHeight = this.getFormHeight(formItem.cardDimension) * 1.05;
249    return formItem;
250  }
251
252  build() {
253    Stack() {
254      Column() {
255        Row() {
256          Image(ThisStyleConstants.FORM_SERVICE_BACK_IMAGE)
257            .width(ThisStyleConstants.FORM_SERVICE_BACK_ICON_WIDTH)
258            .height(ThisStyleConstants.FORM_SERVICE_BACK_ICON_HEIGHT)
259            .onClick(() => {
260              this.backToDeskTop();
261            })
262
263          Text($r('app.string.add_form_to_desktop'))
264            .textAlign(TextAlign.Start)
265            .textOverflow({ overflow: TextOverflow.Ellipsis })
266            .maxLines(1)
267            .fontSize($r('sys.float.ohos_id_text_size_dialog_tittle'))
268            .fontColor($r('sys.color.ohos_id_color_text_primary_contrary'))
269            .fontWeight(ResourceManager.getInstance().getFontWeightMedium())
270            .margin({
271              left: ThisStyleConstants.FORM_SERVICE_BAR_TEXT_MARGIN_LEFT
272            })
273        }
274        .width(this.titleBarWidth)
275        .height(ThisStyleConstants.FORM_SERVICE_BAR_HEIGHT)
276        .margin({
277          top: this.sysUITopHeight
278        })
279
280        Scroll(this.scroller) {
281          Column() {
282            Column() {
283              GridRow({
284                columns: this.gridRowUtils.getColumns(),
285                gutter: {
286                  x: this.gridRowUtils.getGutterX(),
287                  y: $r('sys.float.ohos_id_card_margin_middle')
288                }
289              }) {
290                ForEach(this.showFormInfos, (item: CardItemInfo, index: number) => {
291                  GridCol({
292                    span: item.cardDimension == CommonConstants.CARD_DIMENSION_2x4 ? 4 : 2
293                  }) {
294                    ServiceFormItem({
295                      formItem: item,
296                      mFormItemWidth: this.getFormWidth(item.cardDimension),
297                      mFormItemHeight: this.getFormHeight(item.cardDimension),
298                      idIndex: index
299                    })
300                      .bindContextMenu(this.FormMenuBuilder(item), ResponseType.LongPress)
301                      .bindContextMenu(this.FormMenuBuilder(item), ResponseType.RightClick)
302                      .onClick((event: ClickEvent) => {
303                        this.formClick(event, item);
304                      })
305                  }
306                }, (item: CardItemInfo) => JSON.stringify(item))
307              }
308            }
309            .width(this.formServiceWidth)
310            .margin({
311              top: $r('sys.float.ohos_id_card_margin_middle')
312            })
313
314            List() {
315              ForEach(this.formAppInfos, (item: AppItemInfo, index: number) => {
316                ListItem() {
317                  ServiceFormAppItem({
318                    appName: item.appName,
319                    bundleName: item.bundleName,
320                    abilityName: item.abilityName,
321                    moduleName: item.moduleName,
322                    appLabelId: Number(item.appLabelId).valueOf(),
323                    iconId: item.appIconId,
324                    item: item,
325                    clickApp: this.formAppClick,
326                    idIndex: index
327                  })
328                }
329              }, (item: AppItemInfo) => JSON.stringify(item))
330            }
331            .scrollBar(BarState.Off)
332            .divider({
333              strokeWidth: ThisStyleConstants.SERVICE_FORM_APP_ITEM_GROUP_DIVIDER_WIDTH,
334              color: ThisStyleConstants.FORM_SERVICE_APP_LIST_DIVIDER_COLOR,
335              startMargin: ThisStyleConstants.SERVICE_FORM_APP_ITEM_GROUP_DIVIDER_MARGIN_LEFT,
336              endMargin: 0
337            })
338            .borderRadius(this.cornerRadiusDefaultL)
339            .width(this.formServiceWidth)
340            .backgroundColor(ThisStyleConstants.FORM_SERVICE_APP_LIST_BACKGROUND_COLOR)
341            .padding({
342              top: ThisStyleConstants.FORM_SERVICE_APP_LIST_PADDING_VERTICAL,
343              bottom: ThisStyleConstants.FORM_SERVICE_APP_LIST_PADDING_VERTICAL,
344              left: ThisStyleConstants.FORM_SERVICE_APP_LIST_PADDING_HORIZONTAL,
345              right: ThisStyleConstants.FORM_SERVICE_APP_LIST_PADDING_HORIZONTAL
346            })
347            .margin({
348              top: $r('sys.float.ohos_id_card_margin_middle'),
349              bottom: ThisStyleConstants.FORM_SERVICE_APP_LIST_MARGIN_BOTTOM
350            })
351          }
352          .width(StyleConstants.PERCENTAGE_100)
353          .alignItems(HorizontalAlign.Center)
354        }
355        .align(Alignment.TopStart)
356        .scrollBar(BarState.Off)
357        .width(StyleConstants.PERCENTAGE_100)
358        .height(this.scrollerWrapHeight)
359      }
360      .width(StyleConstants.PERCENTAGE_100)
361      .height(StyleConstants.PERCENTAGE_100)
362    }
363    .width(StyleConstants.PERCENTAGE_100)
364    .height(StyleConstants.PERCENTAGE_100)
365    .backgroundImage(StyleConstants.DEFAULT_FORM_MGR_BACKGROUND_IMAGE)
366    .backgroundBlurStyle(BlurStyle.BACKGROUND_THICK)
367  }
368}
369