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