1/**
2 * Copyright (c) 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 router from '@ohos.router';
17import { ContactVo } from '../../model/bean/ContactVo';
18import DeleteDialogEx from '../../pages/dialog/DeleteDialogEx';
19import ShareDialogEx from '../../pages/dialog/ShareDialogEx';
20import { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil';
21import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog';
22import ContactListPresenter from '../../presenter/contact/ContactListPresenter';
23import EnvironmentProp from '../../feature/EnvironmentProp';
24
25const TAG = 'ContactListItemView ';
26
27/**
28 * The contact item component is used to display a single contact.
29 */
30@Component
31export default struct ContactListItemView {
32  private presenter: ContactListPresenter = ContactListPresenter.getInstance();
33  @State item: ContactVo = new ContactVo('', '', '', '', '', '', true, '', '');
34  @State private index: number = 0;
35  @State showIndex: boolean = false;
36  @State showDivifer: boolean = false;
37  @LocalStorageProp('breakpoint') curBp: string = 'sm';
38  shareDialogControler: CustomDialogController = new CustomDialogController({
39    builder: ShareDialogEx({
40      itemList: this.presenter.shareList,
41      cancel: () => {
42        this.presenter.onShareDialogCancel();
43      },
44      title: $r('app.string.dialog_share'),
45      cancelText: $r('app.string.dialog_cancel')
46    }),
47    autoCancel: false,
48    alignment: (EnvironmentProp.isTablet() ? DialogAlignment.Center : DialogAlignment.Bottom),
49    gridCount: 4
50  });
51  deleteDialogControler: CustomDialogController = new CustomDialogController({
52    builder: DeleteDialogEx({
53      cancel: () => {
54        this.presenter.onDeleteDialogCancel();
55      },
56      confirm: () => {
57        this.presenter.onDeleteDialogConfirm(this.index, this.item);
58      },
59      title: $r('app.string.delete_dialog_title'),
60      cancalText: $r('app.string.dialog_cancel'),
61      confrimText: $r('app.string.dialog_delete')
62    }),
63    autoCancel: false,
64    alignment: (EnvironmentProp.isTablet() ? DialogAlignment.Center : DialogAlignment.Bottom),
65    offset: { dx: 0, dy: -16 },
66    gridCount: 4,
67    closeAnimation: { duration: 100 }
68  });
69
70  aboutToDisappear() {
71    this.shareDialogControler = null;
72    this.deleteDialogControler = null;
73  }
74
75  onDeleteClick() {
76    HiLog.i(TAG, 'onDeleteClick');
77    this.deleteDialogControler.open();
78  }
79
80  onShareClick() {
81    HiLog.i(TAG, 'onShareClick');
82    this.shareDialogControler.open();
83  }
84
85  @Builder MenuBuilder() {
86    Column() {
87      if (this.item.title) {
88        Text(this.item.title)
89          .textAlign(TextAlign.Start)
90          .fontSize($r('sys.float.ohos_id_text_size_headline8'))
91          .fontColor($r('sys.color.ohos_id_color_text_primary'))
92          .fontWeight(FontWeight.Medium)
93          .textOverflow({ overflow: TextOverflow.Ellipsis })
94          .maxLines(1)
95          .height($r('app.float.id_item_height_max'))
96      }
97      Button({ type: ButtonType.Normal, stateEffect: true }) {
98        Text($r('app.string.delete'))
99          .width('100%')
100          .height($r('app.float.id_item_height_mid'))
101          .textAlign(TextAlign.Start)
102          .fontSize($r('sys.float.ohos_id_text_size_body1'))
103          .fontColor($r('sys.color.ohos_id_color_text_primary'))
104          .fontWeight(FontWeight.Regular)
105      }
106      .backgroundColor(Color.White)
107      .onClick(() => {
108        this.presenter.setCurItem(this.item);
109        ContextMenu.close();
110        this.deleteDialogControler.open();
111      })
112    }
113    .alignItems(HorizontalAlign.Start)
114    .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
115    .width($r('app.float.contact_longpress_dialog_width'))
116    .padding({
117      left: $r('app.float.id_card_margin_max'),
118      right: $r('app.float.id_card_margin_max'),
119      top: $r('app.float.id_card_margin_mid'),
120      bottom: $r('app.float.id_card_margin_mid')
121    })
122  }
123
124  build() {
125    Row() {
126      Row() {
127        if (StringUtil.isEmpty(this.item.nameSuffix)) {
128          Image(StringUtil.isEmpty(this.item.portraitPath) ? $r('app.media.ic_user_portrait') : this.item.portraitPath)
129            .width($r('app.float.id_card_image_mid'))
130            .height($r('app.float.id_card_image_mid'))
131            .objectFit(ImageFit.Contain)
132            .borderRadius($r('app.float.id_card_image_mid'))
133            .backgroundColor(this.item.portraitColor)
134        } else {
135          Text(this.item.nameSuffix.toUpperCase())
136            .fontSize(30)
137            .fontWeight(FontWeight.Bold)
138            .fontColor(Color.White)
139            .backgroundColor(this.item.portraitColor)
140            .height($r('app.float.id_card_image_mid'))
141            .width($r('app.float.id_card_image_mid'))
142            .textAlign(TextAlign.Center)
143            .borderRadius($r('app.float.id_card_image_mid'))
144        }
145      }
146      .height($r('app.float.id_card_image_mid'))
147      .width($r('app.float.id_card_image_mid'))
148
149      Column() {
150        Text(this.item.title)
151          .fontColor($r('sys.color.ohos_id_color_text_primary'))
152          .fontSize($r('sys.float.ohos_id_text_size_body1'))
153          .fontWeight(FontWeight.Medium)
154          .margin({ bottom: $r('app.float.id_card_margin_sm') })
155          .textOverflow({ overflow: TextOverflow.Ellipsis })
156          .maxLines(2)
157
158        if (this.item.subTitle) {
159          Text(this.item.subTitle)
160            .width('100%')
161            .fontColor($r('sys.color.ohos_id_color_text_tertiary'))
162            .fontSize($r('sys.float.ohos_id_text_size_body2'))
163            .fontWeight(FontWeight.Regular)
164            .textOverflow({ overflow: TextOverflow.Ellipsis })
165            .maxLines(2)
166        }
167      }
168      .alignItems(HorizontalAlign.Start)
169      .padding({ top: $r('app.float.id_card_margin_mid'), bottom: $r('app.float.id_card_margin_mid'), right: $r('app.float.id_card_margin_xl') })
170      .margin({ left: $r('app.float.id_card_margin_xl'), right: $r('app.float.id_card_margin_xl') })
171    }
172    .constraintSize({ minHeight: $r('app.float.id_item_height_max') })
173    .width('100%')
174    .padding({ top: this.showIndex ? 4 : 0,
175               bottom: this.showDivifer ? 4 : 0,
176               left: this.curBp === 'lg' ? $r('app.float.id_card_margin_max') : 0,
177               right: $r('app.float.id_card_margin_max') })
178    .backgroundColor(Color.White)
179    .borderRadius({
180      topLeft: this.showIndex ? 24 : 0,
181      topRight: this.showIndex ? 24 : 0,
182      bottomLeft: this.showDivifer ? 0 : 24,
183      bottomRight: this.showDivifer ? 0 : 24
184    })
185    .onClick(() => {
186      router.push(
187        {
188          url: 'pages/contacts/details/ContactDetail',
189          params: {
190            sourceHasId: true,
191            contactId: this.item.contactId
192          }
193        }
194      );
195    })
196    .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
197  }
198}