1/*
2 * Copyright (c) 2022-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 BackComponent from '../component/backComponent';
17import Log from '../utils/log';
18import CommonController from '../controller/commonController';
19import EnrollingController from '../controller/enrollingController';
20import CommonUtil from '../utils/CommonUtil';
21
22@Extend(Text) function enrollSetTitleFormat() {
23  .fontColor($r('sys.color.ohos_id_color_text_primary'))
24  .fontSize($r('sys.float.ohos_id_text_size_headline7'))
25  .fontWeight(FontWeight.Bold)
26}
27
28@Extend(Text) function enrollSetSubTitleFormat() {
29  .fontColor($r('sys.color.ohos_id_color_text_primary'))
30  .fontSize($r('sys.float.ohos_id_text_size_sub_title1'))
31  .fontWeight(FontWeight.Medium)
32}
33
34@Entry
35@Component
36struct Enrolling {
37  private readonly TAG: string = 'Enrolling';
38  private xComponentController = new XComponentController();
39  @StorageLink('enrollStatus') enrollStatus: string = '';
40  @StorageLink('stackVideoVisibility') stackVideoVisibility: Visibility = Visibility.Visible;
41  @StorageLink('stackVideoBlurRadius') stackVideoBlurRadius: number = 0;
42  @StorageLink('stackShelterVisibility') stackShelterVisibility: Visibility = Visibility.Visible;
43  @StorageLink('stackShelterHeight') stackShelterHeight : string = '';
44  @StorageLink('stackSuccessVisibility') stackSuccessVisibility: Visibility = Visibility.Hidden;
45  @StorageLink('enrollTip') enrollTip: string = '';
46  @StorageLink('enrollTipSize') enrollTipSize: string = '';
47  @StorageLink('enrollTipVisibility') enrollTipVisibility: Visibility = Visibility.Hidden;
48  @StorageLink('enrollButtonVisibility') enrollButtonVisibility: Visibility = Visibility.Hidden;
49  @StorageLink('enrollImageHeight') enrollImageHeight: number = 0;
50  @StorageLink('enrollImageWidth') enrollImageWidth: number = 0;
51  @StorageLink('xComponentSurfaceId') xComponentSurfaceId : string = '';
52  @StorageLink('BUTTON_TYPE_WIDTH') BUTTON_TYPE_WIDTH: number = 0;
53  @StorageLink('CONTENT_TYPE_WIDTH') CONTENT_TYPE_WIDTH: number = 0;
54  // Ring
55  private settings: RenderingContextSettings = new RenderingContextSettings(true);
56  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
57  @StorageLink('stackRingRadius') stackRingRadius: number = 0;
58  @StorageLink('stackProgressValue') stackProgressValue : number = 0;
59  @StorageLink('stackProgressVisibility') stackProgressVisibility: Visibility = Visibility.Hidden;
60  @StorageLink('animationTime') animationTime: number = 0;
61
62  aboutToAppear() {
63    Log.info(this.TAG, 'aboutToAppear+');
64    EnrollingController.init();
65    Log.info(this.TAG, 'aboutToAppear-');
66  }
67
68  onPageHide() {
69    Log.info(this.TAG, 'onPageHide+');
70    EnrollingController.clear();
71    Log.info(this.TAG, 'onPageHide-');
72  }
73
74  getCanvaRadian(progress : number) : number {
75    return -0.5 * Math.PI + progress * 2 * Math.PI / 100;
76  }
77
78  build() {
79      Column() {
80        BackComponent({prevTag:this.TAG})
81        Text(this.enrollStatus)
82          .enrollSetTitleFormat()
83          .margin({
84            top: '12vp',
85            bottom: '24vp'
86          })
87        Stack() {
88          XComponent({
89            id: 'faceEnrollPreview',
90            type: 'surface',
91            controller: this.xComponentController
92          })
93            .visibility(this.stackVideoVisibility)
94            .height('100%')
95            .width('100%')
96            .markAnchor({ x: '50%', y: '50%'})
97            .position({ x: '50%', y: '50%'})
98            .onLoad(()=>{
99              Log.info(this.TAG, 'onLoad+')
100              this.xComponentSurfaceId = this.xComponentController.getXComponentSurfaceId()
101              EnrollingController.startEnroll()
102              Log.info(this.TAG, 'onLoad-')
103            })
104          Image($r('app.media.shelter'))
105            .objectFit(ImageFit.Contain)
106            .height(this.stackShelterHeight)
107            .width('1000%')
108            .clip(true)
109            .markAnchor({ x: '50%', y: '50%' })
110            .position({ x: '50%', y: '50%' })
111            .animation({ duration: this.animationTime, curve: Curve.Linear })
112            .visibility(this.stackShelterVisibility)
113          Canvas(this.context)
114            .width('100%')
115            .height('100%')
116            .backgroundColor('#00000000')
117            .markAnchor({ x: '50%', y: '50%' })
118            .position({ x: '50%', y: '50%' })
119            .visibility(this.stackProgressVisibility)
120            .onReady(() =>{
121              this.context.imageSmoothingEnabled = true
122              this.context.clearRect(0, 0, this.enrollImageWidth, this.enrollImageHeight)
123              this.context.beginPath()
124              this.context.lineWidth = 4
125              this.context.lineCap = 'round'
126              this.context.strokeStyle = '#08182431'
127              this.context.arc(this.enrollImageWidth / 2, this.enrollImageHeight / 2, this.stackRingRadius,
128                this.getCanvaRadian(0), this.getCanvaRadian(100), false);
129              this.context.stroke()
130              this.context.beginPath()
131              this.context.lineWidth = 5
132              this.context.lineCap = 'round'
133              this.context.strokeStyle = '#007DFF'
134              this.context.arc(this.enrollImageWidth / 2, this.enrollImageHeight / 2, this.stackRingRadius,
135                this.getCanvaRadian(0), this.getCanvaRadian(this.stackProgressValue), false);
136              this.context.stroke()
137            })
138          Image($r('app.media.success'))
139            .objectFit(ImageFit.Contain)
140            .height('84vp')
141            .width('100%')
142            .visibility(this.stackSuccessVisibility)
143        }
144        .height(this.enrollImageHeight)
145        .width(this.enrollImageWidth)
146        .clip(true)
147        Text(this.enrollTip)
148        .enrollSetSubTitleFormat()
149        .fontWeight(FontWeight.Medium)
150        .textAlign(TextAlign.Center)
151        .visibility(this.enrollTipVisibility)
152        .width(this.CONTENT_TYPE_WIDTH)
153        .margin({
154          top: '24vp'
155        })
156        Blank()
157        Button({ type: ButtonType.Capsule, stateEffect: true }) {
158          Text($r('app.string.enroll_button_content'))
159            .fontSize($r('sys.float.ohos_id_text_size_button1'))
160            .fontWeight(FontWeight.Medium)
161            .fontColor($r('sys.color.ohos_id_color_text_primary_activated'))
162        }
163          .backgroundColor($r('sys.color.ohos_id_color_button_normal'))
164          .width(this.BUTTON_TYPE_WIDTH)
165          .height('40vp')
166          .visibility(this.enrollButtonVisibility)
167          .onClick(() => {
168            EnrollingController.init()
169          })
170          .margin({
171            bottom: '24vp',
172          })
173      }
174      .width('100%')
175      .height('100%')
176      .backgroundColor($r('sys.color.ohos_id_color_sub_background'))
177  }
178
179  onBackPress(): boolean {
180    Log.info(this.TAG, 'onBackPress+');
181    CommonController.routeBack();
182    Log.info(this.TAG, 'onBackPress-');
183    return true;
184  }
185}