1/** 2 * Copyright (c) 2021-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 '@system.router'; 17import InputMethod from '@ohos.inputMethod'; 18import { PinSubType } from '../model/passwordImpl/PasswordModel'; 19import PasswordCheckController from '../controller/password/PasswordCheckController'; 20import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 21import Log from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogDecorator'; 22import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData'; 23import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent'; 24 25const DEFAULT_TIMES = 5; 26 27@Entry 28@Component 29struct PasswordCheck { 30 private TAG_PAGE = ConfigData.TAG + 'PasswordCheck page '; 31 private mController: PasswordCheckController = new PasswordCheckController(); 32 33 // bind Properties 34 private pinToken: string = ''; 35 @State @Watch("freezeView") 36 private freezingTime: number = 0; 37 @State @Watch("updateView") 38 private remainTimes: number = -1; 39 40 // handler 41 private passwordOnChangeHandler: (value: string) => void = () => {}; 42 private okOnClickHandler: (event?: ClickEvent) => void = () => {}; 43 44 // private Properties 45 private pageRequestCode: number = -1; 46 private prevPageUri: string = ''; 47 private pinChallenge: string = ''; 48 private timerId: number = -1; 49 private freezingTimeFlag: number = 0; 50 51 @State private passwordType: number = -1; 52 @State private promptMessage:string = '' 53 @State private buttonVisibility: Visibility = Visibility.Visible; 54 @State private freezingTimeForView: number = -1; 55 @State private password: string = ''; 56 @State isTouchedLeft: boolean = false; 57 @State isTouchedRight: boolean = false; 58 59 aboutToAppear(): void { 60 this.getRouterParam(); 61 62 // bind event handlers 63 this.passwordOnChangeHandler = (value: string):void => this.mController.passwordOnChange(value); 64 this.okOnClickHandler = (event?: ClickEvent):void => this.mController.inputFinish(event); 65 66 // bind component and initialize 67 this.mController.bindComponent(this) 68 .bindProperties(["freezingTime", "remainTimes", "pinToken", "password"]) 69 .initData() 70 .subscribe(); 71 72 this.updateView(); 73 } 74 75 aboutToDisappear(): void { 76 this.mController.unsubscribe(); 77 this.stopCountDown(); 78 } 79 80 /** 81 * Get the params from router 82 */ 83 getRouterParam() { 84 let param = Router.getParams(); 85 if (!param) { 86 return; 87 } 88 this.pageRequestCode = param.pageRequestCode as number; 89 this.prevPageUri = param.prevPageUri as string; 90 this.pinChallenge = param.pinChallenge as string; 91 this.passwordType = param.passwordType as number; 92 } 93 94 build() { 95 Column() { 96 GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) { 97 Column() { 98 // head 99 HeadComponent({ headName: $r('app.string.password_enter_password'), isActive: true }) 100 101 // freeze view 102 if (this.freezingTimeForView > 0) { 103 Row() { 104 // attempt seconds 105 Text($r('app.string.password_remain_times', this.freezingTimeForView)) 106 .fontSize($r('app.float.font_28')) 107 .fontColor(Color.Blue) 108 .textCase(TextCase.UpperCase) 109 .margin({ 110 top: $r('app.float.password_input_message_vertical_margin'), 111 bottom: $r('app.float.password_input_message_vertical_margin') 112 }) 113 .padding({ 114 left: $r('app.float.item_common_horizontal_margin'), 115 right: $r('app.float.item_common_horizontal_margin') 116 }) 117 .align(Alignment.Center) 118 } 119 .backgroundColor(Color.Gray) 120 .margin({ 121 left: $r('app.float.password_count_down_view_vertical_margin'), 122 right: $r('app.float.password_count_down_view_vertical_margin') 123 }) 124 125 // input 126 } else { 127 Column() { 128 // input message 129 Text(' ') 130 .fontSize($r('sys.float.ohos_id_text_size_sub_title2')) 131 .fontWeight(FontWeight.Medium) 132 .fontColor($r('sys.color.ohos_id_color_foreground')) 133 .margin({ top: $r('app.float.item_common_horizontal_margin') }) 134 .align(Alignment.Center) 135 .visibility(Visibility.Hidden) 136 137 // input password 138 Row() { 139 TextInput({ placeholder: '', text: this.password }) 140 .placeholderFont({ 141 size: $r("app.float.font_18"), 142 weight: FontWeight.Normal, 143 style: FontStyle.Normal 144 }) 145 .type(InputType.Password) 146 .enterKeyType(EnterKeyType.Done) 147 .caretColor(Color.Blue) 148 .padding({ 149 left: $r('sys.float.ohos_id_card_margin_start'), 150 right: $r('sys.float.ohos_id_card_margin_end') 151 }) 152 .margin({ top: $r('app.float.wh_value_50') }) 153 .height($r("app.float.wh_value_40")) 154 .layoutWeight(ConfigData.LAYOUT_WEIGHT_1) 155 .borderRadius(0) 156 .backgroundColor($r('app.color.color_00000000_transparent')) 157 .onChange(this.passwordOnChangeHandler) 158 .onSubmit((enterKey) => { 159 InputMethod.getInputMethodController().stopInput() 160 .then((ret) => { 161 LogUtil.debug(`${ConfigData.TAG}, enterType: ${enterKey}, stopInput: ${ret}`); 162 }); 163 }) 164 } 165 166 Divider() 167 .padding({ left: $r('sys.float.ohos_id_card_margin_start'), right: $r('sys.float.ohos_id_card_margin_end') }) 168 .color($r("sys.color.ohos_id_color_list_separator")) 169 170 // prompt message 171 Text(this.promptMessage) 172 .fontSize($r('sys.float.ohos_id_text_size_body2')) 173 .fontWeight(FontWeight.Medium) 174 .fontColor($r('sys.color.ohos_id_color_warning')) 175 .align(Alignment.Center) 176 .textAlign(TextAlign.Center) 177 .margin({ top: $r('app.float.distance_14'), bottom: $r('app.float.distance_32') }) 178 .visibility(this.remainTimes === 0 ? Visibility.Hidden : Visibility.Visible) 179 180 // button 181 Flex({ justifyContent: FlexAlign.SpaceBetween }) { 182 Row() { 183 Button({ type: ButtonType.Capsule, stateEffect: true }) { 184 Text($r('app.string.cancel')) 185 .fontSize($r('app.float.font_16')) 186 .fontWeight(FontWeight.Medium) 187 .lineHeight($r('app.float.wh_value_22')) 188 .fontColor($r('app.color.font_color_007DFF')) 189 .textAlign(TextAlign.Center) 190 .height($r('app.float.application_button_height')) 191 } 192 .layoutWeight(ConfigData.LAYOUT_WEIGHT_1) 193 .backgroundColor(!this.isTouchedLeft ? $r("sys.color.ohos_id_color_button_normal") : $r("sys.color.ohos_id_color_foreground_contrary")) 194 .onTouch((event?: TouchEvent) => { 195 if (event?.type === TouchType.Down) { 196 this.isTouchedLeft = true; 197 } 198 199 if (event?.type === TouchType.Up) { 200 this.isTouchedLeft = false; 201 } 202 }) 203 .onClick(() => { 204 Router.back(); 205 }) 206 207 Column() 208 .width( $r('app.float.distance_12')) 209 .height($r('app.float.application_button_height')) 210 211 Button({ type: ButtonType.Capsule, stateEffect: true }) { 212 Text($r('app.string.next')) 213 .fontSize($r('app.float.font_16')) 214 .fontWeight(FontWeight.Medium) 215 .lineHeight($r('app.float.wh_value_22')) 216 .fontColor($r('app.color.font_color_007DFF')) 217 .height($r('app.float.application_button_height')) 218 .textAlign(TextAlign.Center) 219 } 220 .layoutWeight(ConfigData.LAYOUT_WEIGHT_1) 221 .backgroundColor(!this.isTouchedLeft ? '#E6E9EB' : $r("sys.color.ohos_id_color_foreground_contrary")) 222 .onTouch((event?: TouchEvent) => { 223 if (event?.type === TouchType.Down) { 224 this.isTouchedRight = true; 225 } 226 227 if (event?.type === TouchType.Up) { 228 this.isTouchedRight = false; 229 } 230 }) 231 .onClick(this.okOnClickHandler) 232 } 233 .alignItems(VerticalAlign.Center) 234 .width(ConfigData.WH_100_100) 235 .padding({ 236 top: $r('app.float.distance_24'), 237 bottom: $r('app.float.distance_36'), 238 }) 239 .margin({ top: $r('app.float.distance_66') }) 240 .visibility(this.buttonVisibility) 241 } 242 } 243 } 244 } 245 .useSizeType({ 246 sm: { span: 4, offset: 0 }, 247 md: { span: 6, offset: 1 }, 248 lg: { span: 8, offset: 2 } 249 }) 250 } 251 .width(ConfigData.WH_100_100) 252 .height(ConfigData.WH_100_100) 253 } 254 .backgroundColor($r("sys.color.ohos_id_color_sub_background")) 255 .width(ConfigData.WH_100_100) 256 .height(ConfigData.WH_100_100) 257 } 258 259 // --------------------------- updateView ----------------------- 260 /** 261 * Update view 262 */ 263 updateView() { 264 this.promptMessage = this.getPromptMessage(); 265 this.buttonVisibility = this.getButtonVisibility(); 266 } 267 268 /** 269 * Get prompt message 270 * 271 * @return : message 272 */ 273 getPromptMessage(): string { 274 return (this.remainTimes > 0 && this.remainTimes < DEFAULT_TIMES) ? JSON.parse(JSON.stringify($r('app.string.password_message_incorrect', this.remainTimes))) : ''; 275 } 276 277 /** 278 * Get button visibility 279 * 280 * @return : button visibility 281 */ 282 getButtonVisibility(): Visibility { 283 return this.passwordType == PinSubType.PIN_SIX ? Visibility.Hidden : Visibility.Visible; 284 } 285 286 /** 287 * When freezing time is greater than 0, start count down view. 288 * 289 * @return : button visibility 290 */ 291 freezeView() { 292 if (this.freezingTime <= 0) { 293 this.stopCountDown(); 294 return; 295 } 296 297 this.freezingTimeForView = this.freezingTime / 1000; 298 LogUtil.info(this.TAG_PAGE + `freezeView freezingTimeForView = ${this.freezingTimeForView}`); 299 this.freezingTimeFlag = setTimeout(() => { 300 this.freezingTimeForView = 0; 301 }, this.freezingTime); 302 this.timerId = setInterval(() => { 303 if (this.freezingTimeForView <= 0) { 304 this.stopCountDown(); 305 this.timerId = -1; 306 this.freezingTimeForView = 0; 307 this.freezingTime = 0; 308 this.updateView(); 309 } else { 310 this.freezingTimeForView -= 1; 311 } 312 }, 1000) 313 } 314 315 /** 316 * Stop count down view. 317 */ 318 stopCountDown() { 319 // for freezing view 320 if (this.timerId > 0) { 321 clearTimeout(this.freezingTimeFlag); 322 clearInterval(this.timerId); 323 } 324 } 325}