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 Logger from '../mode/Logger'; 17import vibrator from '@ohos.vibrator'; 18import { TextDialog } from '../common/TextDialog'; 19import { TimerPicker } from '../common/TimerPicker'; 20 21let TAG = '[TextTimerComponent]'; 22const HOUR_MS = 3600 * 1000; 23const MINUTE_MS = 60 * 1000; 24const SECOND_MS = 1000; 25const TOTAL = 100; 26 27@Component 28export struct TextTimerComponent { 29 @State @Watch('onChange') hours: number = 0; 30 @State @Watch('onChange') minutes: number = 0; 31 @State @Watch('onChange') seconds: number = 0; 32 @State duration: number = 0; 33 @State progressValue: number = 0; 34 @State hourText: string = '00'; 35 @State minuteText: string = '00'; 36 @State secondText: string = '00'; 37 @State textStr: string = ''; 38 private vibrationDuration: number = 10000; 39 private timeout: number = 10000; 40 private counts: number; 41 private timerId: number; 42 private timerPicker: CustomDialogController = new CustomDialogController({ 43 builder: TimerPicker({ hours: $hours, minutes: $minutes, seconds: $seconds, duration: $duration }), 44 autoCancel: true 45 }) 46 private textDialog: CustomDialogController = new CustomDialogController({ 47 builder: TextDialog(), 48 autoCancel: true 49 }) 50 51 formatTime(value: number) { 52 return (value > 9 ? '' : '0') + value; 53 } 54 55 onChange() { 56 this.hourText = this.formatTime(this.hours); 57 this.minuteText = this.formatTime(this.minutes); 58 this.secondText = this.formatTime(this.seconds); 59 this.textStr = `${this.hourText} : ${this.minuteText} : ${this.secondText}`; 60 } 61 62 aboutToAppear() { 63 this.textStr = `${this.hourText} : ${this.minuteText} : ${this.secondText}`; 64 } 65 66 build() { 67 Column() { 68 Progress({ value: this.progressValue, total: TOTAL, style: ProgressStyle.Ring }) 69 .width(150) 70 .margin({ bottom: 60 }) 71 Column() { 72 Text(this.textStr) 73 .fontSize(35) 74 .id('countdownTime') 75 } 76 .margin({ bottom: 80 }) 77 .onClick(() => { 78 if(this.hours === 0 && this.minutes === 0 && this.seconds === 0) { 79 this.timerPicker.open(); 80 } 81 }) 82 83 Button('start') 84 .width(200) 85 .fontSize(30) 86 .margin({ top: 20 }) 87 .backgroundColor('#0D9FFB') 88 .id('start') 89 .onClick(() => { 90 if(this.timerId) { 91 clearInterval(this.timerId); 92 } 93 this.timerId = setInterval(() => { 94 Logger.info(TAG, `countdown hours: ${this.hours}, minutes: ${this.minutes}, seconds: ${this.seconds}`); 95 this.counts = this.hours * HOUR_MS + this.minutes * MINUTE_MS + this.seconds * SECOND_MS; 96 this.progressValue += TOTAL / this.duration; 97 Logger.info(TAG, `counts is: ${this.counts}`); 98 if (this.counts > 0) { 99 this.counts = this.counts - SECOND_MS; 100 Logger.info(TAG, `countdown counts = ${this.counts}, progress = ${this.progressValue}`); 101 102 this.hours = Math.floor(this.counts / HOUR_MS); 103 this.counts = this.counts - this.hours * HOUR_MS; 104 105 this.minutes = Math.floor(this.counts / MINUTE_MS); 106 this.counts = this.counts - this.minutes * MINUTE_MS; 107 108 this.seconds = Math.floor(this.counts / SECOND_MS); 109 } 110 if (this.hours === 0 && this.minutes === 0 && this.seconds === 0) { 111 try { 112 vibrator.startVibration({ 113 type: 'time', 114 duration: this.vibrationDuration, 115 }, { 116 id: 0, 117 usage: 'simulateReality' 118 }, (error) => { 119 if (error) { 120 Logger.error(TAG, `error.code = ${error.code}, error.message = ${error.message}`); 121 return; 122 } 123 Logger.info(TAG, `${TAG} Callback returned to indicate a successful vibration`); 124 this.textDialog.open(); 125 this.progressValue = 0; 126 setTimeout(() => { 127 this.textDialog.close(); 128 }, this.timeout) 129 clearInterval(this.timerId); 130 }); 131 } catch (err) { 132 Logger.error(TAG, `catch error.code = ${err.code}, error.message = ${err.message}`); 133 } 134 } 135 }, 1000) 136 }) 137 Button('reset') 138 .width(200) 139 .fontSize(30) 140 .margin({ top: 40 }) 141 .backgroundColor('#0D9FFB') 142 .id('reset') 143 .onClick(() => { 144 this.hours = 0; 145 this.minutes = 0; 146 this.seconds = 0; 147 this.progressValue = 0; 148 this.textStr = '00:00:00'; 149 clearInterval(this.timerId); 150 }) 151 } 152 .width('100%') 153 .height('100%') 154 } 155}