1/**
2 * Copyright (c) 2024-2024 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 HeadComponent from '../../common/component/headComponent';
17import { WidthPercent } from '../../common/util/ConfigData';
18import CmShowUserCaPresenter from '../../presenter/CmShowUserCaPresenter';
19import {
20  DialogDateComponent,
21  DialogFingerPrintComponent,
22  DialogIssuerComponent,
23  DialogSubjectComponent
24} from '../trustedCa';
25import { AlertDialog } from '@ohos.arkui.advanced.Dialog';
26import { BusinessError } from '@ohos.base';
27import { SheetParam } from './SheetParam';
28import { NavEntryKey } from '../../common/NavEntryKey';
29
30const TAG: string = 'CaUserDetailPage: ';
31
32export class CaUserDetailParam {
33  public showUserCaPresenter: CmShowUserCaPresenter;
34
35  constructor(presenter: CmShowUserCaPresenter) {
36    this.showUserCaPresenter = presenter;
37  }
38}
39
40@Component
41export struct CaUserDetailPage {
42  private showUserCaPresenter: CmShowUserCaPresenter = CmShowUserCaPresenter.getInstance();
43
44  private stack?: NavPathStack;
45
46  @State private bottomRectHeight: number = 80;
47  @State private headRectHeight: number = 64;
48  @State private headRectHeightReal: number = 0;
49
50  @State toggleStatus: boolean = false;
51  @Prop sheetParam: SheetParam;
52
53  rootCertificateDialog: CustomDialogController = new CustomDialogController({
54    alignment: DialogAlignment.Center,
55    cancel: () => {
56      this.toggleStatus = false;
57    },
58    builder: AlertDialog({
59      primaryTitle: $r('app.string.root_certificate'),
60      content: $r('app.string.root_certificate_message'),
61      primaryButton: {
62        value: $r('app.string.root_certificate_cancel'),
63        buttonStyle: ButtonStyleMode.TEXTUAL,
64        action: () => {
65          this.toggleStatus = false;
66          this.showUserCaPresenter.updateUserTrustedCertificateList();
67        }
68      },
69      secondaryButton: {
70        value: $r('app.string.root_certificate_continue'),
71        buttonStyle: ButtonStyleMode.TEXTUAL,
72        action: () => {
73          this.showUserCaPresenter.setUserCertificateStatus(this.showUserCaPresenter.certInfo.uri, true)
74            .then(result => {
75              if (result) {
76                this.showUserCaPresenter.updateUserTrustedCertificateList();
77              } else {
78                this.toggleStatus = false;
79              }
80          });
81        }
82      }
83    })
84  })
85
86  deleteCertWarnDialog: CustomDialogController = new CustomDialogController({
87    builder: AlertDialog({
88      primaryTitle: $r('app.string.CustomDialogExampleUser_warning_Button_title_text'),
89      content: $r('app.string.CustomDialogExampleUser_warning_Button_message_text'),
90      primaryButton: {
91        value: $r('app.string.deleteAllCredCancel'),
92        buttonStyle: ButtonStyleMode.TEXTUAL,
93        action: () => {
94        }
95      },
96      secondaryButton: {
97        value: $r('app.string.deleteAllCredDelete'),
98        buttonStyle: ButtonStyleMode.TEXTUAL,
99        action: () => {
100          this.showUserCaPresenter.deleteUserCertificate(this.showUserCaPresenter.certInfo.uri, () => {
101            this.showUserCaPresenter.updateUserTrustedCertificateList();
102          })
103          this.stack?.pop();
104        },
105        role: ButtonRole.ERROR
106      }
107    })
108  })
109
110  build() {
111    NavDestination() {
112      Stack({ alignContent: Alignment.Bottom }) {
113        Stack({ alignContent: Alignment.Top }) {
114          Column() {
115            HeadComponent({ headName: $r('app.string.CustomDialogExample_firText'), isStartBySheet: true, onBackClicked: () => {
116              this.stack?.pop();
117            } })
118              .margin({
119                left: $r('app.float.wh_value_12'),
120                top: 8
121              })
122          }.zIndex(1)
123          .onAreaChange((oldArea, newArea) => {
124            this.headRectHeight = newArea.height as number;
125            this.headRectHeightReal = newArea.height as number;
126          })
127
128          Stack({ alignContent: Alignment.TopEnd }) {
129            Scroll() {
130              this.buildContent()
131            }
132            .padding({
133              left: 16, right: 16
134            })
135            .align(Alignment.Top)
136            .scrollable(ScrollDirection.Vertical)
137            .scrollBar(BarState.Auto)
138            .edgeEffect(EdgeEffect.Spring)
139            .width(WidthPercent.WH_100_100)
140            .height(WidthPercent.WH_AUTO)
141            .constraintSize({
142              minHeight: this.getScrollMinHeight()
143            })
144          }.padding({
145            top: this.headRectHeight
146          })
147        }
148        .width(WidthPercent.WH_100_100)
149        .height(WidthPercent.WH_AUTO)
150        .padding({
151          bottom: this.bottomRectHeight
152        })
153
154        Column() {
155          Button($r('app.string.CustomDialogExampleUser_warning_Button_title_text'))
156            .onClick(() => {
157              this.deleteCertWarnDialog.open();
158            })
159            .role(ButtonRole.ERROR)
160            .buttonStyle(ButtonStyleMode.NORMAL)
161            .margin({
162              top: $r('app.float.distance_16'),
163              bottom: $r('app.float.distance_24')
164            })
165            .width(WidthPercent.WH_100_100)
166        }.onAreaChange((oldArea: Area, newArea: Area) => {
167          this.bottomRectHeight = newArea.height as number;
168        })
169        .padding({
170          left: 16, right: 16
171        })
172      }
173    }
174    .hideTitleBar(true)
175    .width(WidthPercent.WH_100_100)
176    .height(this.sheetParam?.lastSheetPage === NavEntryKey.CA_USER_DETAIL_ENTRY ?
177      WidthPercent.WH_AUTO : this.sheetParam?.sheetMinHeight)
178    .backgroundColor($r('sys.color.background_secondary'))
179    .onReady((ctx: NavDestinationContext) => {
180      this.stack = ctx.pathStack;
181      try {
182        this.showUserCaPresenter = (ctx.pathInfo.param as CaUserDetailParam).showUserCaPresenter;
183        this.toggleStatus = this.showUserCaPresenter.certInfo.status;
184      } catch (err) {
185        let error = err as BusinessError;
186        console.error(TAG + 'Get presenter failed: ' + error?.code + ', message: ' + error?.message);
187      }
188    })
189  }
190
191  @Builder
192  private buildContent() {
193    Column() {
194      Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
195        Column() {
196          Text(this.showUserCaPresenter.certInfo.certAlias)
197            .fontSize($r('sys.float.ohos_id_text_size_body1'))
198            .fontColor($r('sys.color.ohos_id_color_text_primary'))
199            .fontWeight(FontWeight.Medium)
200        }.alignItems(HorizontalAlign.Start);
201
202        Toggle({ type: ToggleType.Switch, isOn: $$this.toggleStatus })
203          .margin({
204            left: $r('app.float.wh_value_5')
205          })
206          .flexShrink(0)
207          .onChange((isOn: boolean) => {
208            if (isOn) {
209              this.rootCertificateDialog.open();
210            } else {
211              this.showUserCaPresenter.setUserCertificateStatus(this.showUserCaPresenter.certInfo.uri, false);
212            }
213          })
214      }.margin({ top: 8 })
215
216      Text($r('app.string.CustomDialogExample_firListItem_text'))
217        .fontSize($r('sys.float.ohos_id_text_size_body1'))
218        .fontColor($r('sys.color.ohos_id_color_text_primary'))
219        .fontWeight(FontWeight.Medium)
220        .margin({
221          top: $r('app.float.wh_value_24')
222        })
223
224      DialogSubjectComponent({ map: this.showUserCaPresenter.certInfo.subjectNameMap })
225
226      Text($r('app.string.CustomDialogExample_secListItem_text'))
227        .fontSize($r('sys.float.ohos_id_text_size_body1'))
228        .fontColor($r('sys.color.ohos_id_color_text_primary'))
229        .fontWeight(FontWeight.Medium)
230        .margin({
231          top: $r('app.float.wh_value_24')
232        })
233
234      DialogIssuerComponent({ map: this.showUserCaPresenter.certInfo.issuerNameMap })
235
236      Text($r('app.string.CustomDialogExample_thdListItem_text'))
237        .fontSize($r('sys.float.ohos_id_text_size_body1'))
238        .fontColor($r('sys.color.ohos_id_color_text_primary'))
239        .fontWeight(FontWeight.Medium)
240        .margin({
241          top: $r('app.float.wh_value_24')
242        })
243
244      DialogDateComponent({ map: this.showUserCaPresenter.certInfo.dateMap })
245
246      Text($r('app.string.CustomDialogExample_fouListItem_text'))
247        .fontSize($r('sys.float.ohos_id_text_size_body1'))
248        .fontColor($r('sys.color.ohos_id_color_text_primary'))
249        .fontWeight(FontWeight.Medium)
250        .margin({
251          top: $r('app.float.wh_value_24')
252        })
253
254      DialogFingerPrintComponent({
255        fingerprintSha256: this.showUserCaPresenter.certInfo.fingerprintSha256
256      })
257    }
258    .width(WidthPercent.WH_100_100)
259    .alignItems(HorizontalAlign.Start)
260  }
261
262  getScrollMinHeight() {
263    if (this.sheetParam === undefined || this.headRectHeightReal === 0 ||
264      this.sheetParam.sheetMinHeight < (this.headRectHeightReal + this.bottomRectHeight)) {
265      return 0;
266    }
267    return this.sheetParam.sheetMinHeight - this.headRectHeightReal - this.bottomRectHeight;
268  }
269}