From 05a2cfee7ba20f963528eb3880fd22e89a62b782 Mon Sep 17 00:00:00 2001 From: ding_chengjie Date: Wed, 19 Oct 2022 11:32:38 +0800 Subject: [PATCH 01/19] commit the initial version for applications_clock Signed-off-by: ding_chengjie --- .gitignore | 8 + AppScope/app.json5 | 11 + AppScope/resources/base/element/string.json | 8 + AppScope/resources/base/media/app_icon.png | Bin 0 -> 4155 bytes LICENSE | 201 +++++++++++++ README.en.md | 36 --- README.md | 81 +++--- build-profile.json5 | 52 ++++ common/.gitignore | 3 + common/build-profile.json5 | 5 + common/hvigorfile.js | 3 + common/index.ets | 21 ++ common/package-lock.json | 5 + common/package.json | 14 + .../main/ets/components/imageComponent.ets | 31 ++ common/src/main/ets/utils/ConfigData.ets | 63 ++++ common/src/main/ets/utils/LogUtil.ts | 48 ++++ common/src/main/ets/utils/TimerUtil.ets | 55 ++++ common/src/main/module.json5 | 11 + .../main/resources/base/element/color.json | 24 ++ .../main/resources/base/element/string.json | 20 ++ .../resources/base/media/ic_clock_clock.svg | 12 + .../base/media/ic_clock_clock_click.svg | 12 + .../resources/base/media/ic_clock_play.svg | 7 + .../resources/base/media/ic_clock_refresh.svg | 7 + .../media/ic_clock_second_chronograph.svg | 9 + .../ic_clock_second_chronograph_click.svg | 9 + .../resources/base/media/ic_clock_sound.svg | 7 + .../resources/base/media/ic_clock_suspend.svg | 8 + .../resources/base/media/ic_clock_timer.svg | 10 + .../resources/base/media/ic_clock_timer2.svg | 10 + .../base/media/ic_clock_timer_click.svg | 10 + feature/countdown/.gitignore | 3 + feature/countdown/build-profile.json5 | 5 + feature/countdown/hvigorfile.js | 3 + feature/countdown/index.ets | 19 ++ feature/countdown/package-lock.json | 11 + feature/countdown/package.json | 16 ++ .../src/main/ets/components/CountdownView.ets | 111 +++++++ .../main/ets/components/TimeSelectView.ets | 126 ++++++++ .../ets/controller/CountdownController.ets | 271 ++++++++++++++++++ feature/countdown/src/main/module.json5 | 11 + .../main/resources/base/element/color.json | 20 ++ .../main/resources/base/element/float.json | 48 ++++ .../main/resources/base/element/string.json | 20 ++ feature/timer/.gitignore | 3 + feature/timer/build-profile.json5 | 5 + feature/timer/hvigorfile.js | 3 + feature/timer/index.ets | 17 ++ feature/timer/package-lock.json | 11 + feature/timer/package.json | 16 ++ .../src/main/ets/components/TimerView.ets | 229 +++++++++++++++ .../main/ets/controller/TimerController.ets | 247 ++++++++++++++++ feature/timer/src/main/module.json5 | 11 + .../main/resources/base/element/color.json | 12 + .../main/resources/base/element/string.json | 8 + figures/clock.png | Bin 0 -> 10250 bytes hvigorfile.js | 2 + package.json | 18 ++ product/pc/.gitignore | 4 + product/pc/build-profile.json5 | 13 + product/pc/hvigorfile.js | 2 + product/pc/package-lock.json | 33 +++ product/pc/package.json | 18 ++ .../main/ets/Application/MyAbilityStage.ts | 21 ++ .../src/main/ets/MainAbility/MainAbility.ts | 55 ++++ product/pc/src/main/ets/pages/Countdown.ets | 178 ++++++++++++ product/pc/src/main/ets/pages/index.ets | 84 ++++++ .../ets/pages/timer/CurrentTimeDisplay.ets | 45 +++ .../src/main/ets/pages/timer/TimeOfRecord.ets | 68 +++++ product/pc/src/main/ets/pages/timer/Timer.ets | 69 +++++ .../src/main/ets/pages/timer/TimerClock.ets | 35 +++ .../src/main/ets/pages/timer/TimerControl.ets | 84 ++++++ product/pc/src/main/module.json5 | 43 +++ .../main/resources/base/element/color.json | 12 + .../main/resources/base/element/float.json | 120 ++++++++ .../main/resources/base/element/string.json | 16 ++ .../pc/src/main/resources/base/media/icon.png | Bin 0 -> 4155 bytes .../resources/base/profile/main_pages.json | 5 + .../ets/Application/TestAbilityStage.ts | 7 + .../ohosTest/ets/TestAbility/TestAbility.ts | 45 +++ .../ohosTest/ets/TestAbility/pages/index.ets | 34 +++ .../ets/TestRunner/OpenHarmonyTestRunner.ts | 64 +++++ .../pc/src/ohosTest/ets/test/Ability.test.ets | 13 + .../pc/src/ohosTest/ets/test/List.test.ets | 5 + product/pc/src/ohosTest/module.json5 | 39 +++ .../resources/base/element/color.json | 8 + .../resources/base/element/string.json | 16 ++ .../ohosTest/resources/base/media/icon.png | Bin 0 -> 6790 bytes .../resources/base/profile/test_pages.json | 5 + product/phone/.gitignore | 4 + product/phone/build-profile.json5 | 13 + product/phone/hvigorfile.js | 2 + product/phone/package-lock.json | 33 +++ product/phone/package.json | 18 ++ .../main/ets/Application/MyAbilityStage.ts | 21 ++ .../src/main/ets/MainAbility/MainAbility.ts | 55 ++++ .../phone/src/main/ets/pages/Countdown.ets | 157 ++++++++++ product/phone/src/main/ets/pages/index.ets | 82 ++++++ .../ets/pages/timer/CurrentTimeDisplay.ets | 45 +++ .../src/main/ets/pages/timer/TimeOfRecord.ets | 71 +++++ .../phone/src/main/ets/pages/timer/Timer.ets | 78 +++++ .../src/main/ets/pages/timer/TimerClock.ets | 35 +++ .../src/main/ets/pages/timer/TimerControl.ets | 74 +++++ product/phone/src/main/module.json5 | 38 +++ .../main/resources/base/element/float.json | 129 +++++++++ .../main/resources/base/element/string.json | 16 ++ .../src/main/resources/base/media/icon.png | Bin 0 -> 4155 bytes .../resources/base/profile/main_pages.json | 5 + .../ets/Application/TestAbilityStage.ts | 7 + .../ohosTest/ets/TestAbility/TestAbility.ts | 45 +++ .../ohosTest/ets/TestAbility/pages/index.ets | 34 +++ .../ets/TestRunner/OpenHarmonyTestRunner.ts | 64 +++++ .../src/ohosTest/ets/test/Ability.test.ets | 13 + .../phone/src/ohosTest/ets/test/List.test.ets | 5 + product/phone/src/ohosTest/module.json5 | 38 +++ .../resources/base/element/color.json | 8 + .../resources/base/element/string.json | 16 ++ .../ohosTest/resources/base/media/icon.png | Bin 0 -> 6790 bytes .../resources/base/profile/test_pages.json | 5 + 120 files changed, 4224 insertions(+), 75 deletions(-) create mode 100644 .gitignore create mode 100644 AppScope/app.json5 create mode 100644 AppScope/resources/base/element/string.json create mode 100644 AppScope/resources/base/media/app_icon.png create mode 100644 LICENSE delete mode 100644 README.en.md create mode 100644 build-profile.json5 create mode 100644 common/.gitignore create mode 100644 common/build-profile.json5 create mode 100644 common/hvigorfile.js create mode 100644 common/index.ets create mode 100644 common/package-lock.json create mode 100644 common/package.json create mode 100644 common/src/main/ets/components/imageComponent.ets create mode 100644 common/src/main/ets/utils/ConfigData.ets create mode 100644 common/src/main/ets/utils/LogUtil.ts create mode 100644 common/src/main/ets/utils/TimerUtil.ets create mode 100644 common/src/main/module.json5 create mode 100644 common/src/main/resources/base/element/color.json create mode 100644 common/src/main/resources/base/element/string.json create mode 100644 common/src/main/resources/base/media/ic_clock_clock.svg create mode 100644 common/src/main/resources/base/media/ic_clock_clock_click.svg create mode 100644 common/src/main/resources/base/media/ic_clock_play.svg create mode 100644 common/src/main/resources/base/media/ic_clock_refresh.svg create mode 100644 common/src/main/resources/base/media/ic_clock_second_chronograph.svg create mode 100644 common/src/main/resources/base/media/ic_clock_second_chronograph_click.svg create mode 100644 common/src/main/resources/base/media/ic_clock_sound.svg create mode 100644 common/src/main/resources/base/media/ic_clock_suspend.svg create mode 100644 common/src/main/resources/base/media/ic_clock_timer.svg create mode 100644 common/src/main/resources/base/media/ic_clock_timer2.svg create mode 100644 common/src/main/resources/base/media/ic_clock_timer_click.svg create mode 100644 feature/countdown/.gitignore create mode 100644 feature/countdown/build-profile.json5 create mode 100644 feature/countdown/hvigorfile.js create mode 100644 feature/countdown/index.ets create mode 100644 feature/countdown/package-lock.json create mode 100644 feature/countdown/package.json create mode 100644 feature/countdown/src/main/ets/components/CountdownView.ets create mode 100644 feature/countdown/src/main/ets/components/TimeSelectView.ets create mode 100644 feature/countdown/src/main/ets/controller/CountdownController.ets create mode 100644 feature/countdown/src/main/module.json5 create mode 100644 feature/countdown/src/main/resources/base/element/color.json create mode 100644 feature/countdown/src/main/resources/base/element/float.json create mode 100644 feature/countdown/src/main/resources/base/element/string.json create mode 100644 feature/timer/.gitignore create mode 100644 feature/timer/build-profile.json5 create mode 100644 feature/timer/hvigorfile.js create mode 100644 feature/timer/index.ets create mode 100644 feature/timer/package-lock.json create mode 100644 feature/timer/package.json create mode 100644 feature/timer/src/main/ets/components/TimerView.ets create mode 100644 feature/timer/src/main/ets/controller/TimerController.ets create mode 100644 feature/timer/src/main/module.json5 create mode 100644 feature/timer/src/main/resources/base/element/color.json create mode 100644 feature/timer/src/main/resources/base/element/string.json create mode 100644 figures/clock.png create mode 100644 hvigorfile.js create mode 100644 package.json create mode 100644 product/pc/.gitignore create mode 100644 product/pc/build-profile.json5 create mode 100644 product/pc/hvigorfile.js create mode 100644 product/pc/package-lock.json create mode 100644 product/pc/package.json create mode 100644 product/pc/src/main/ets/Application/MyAbilityStage.ts create mode 100644 product/pc/src/main/ets/MainAbility/MainAbility.ts create mode 100644 product/pc/src/main/ets/pages/Countdown.ets create mode 100644 product/pc/src/main/ets/pages/index.ets create mode 100644 product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets create mode 100644 product/pc/src/main/ets/pages/timer/TimeOfRecord.ets create mode 100644 product/pc/src/main/ets/pages/timer/Timer.ets create mode 100644 product/pc/src/main/ets/pages/timer/TimerClock.ets create mode 100644 product/pc/src/main/ets/pages/timer/TimerControl.ets create mode 100644 product/pc/src/main/module.json5 create mode 100644 product/pc/src/main/resources/base/element/color.json create mode 100644 product/pc/src/main/resources/base/element/float.json create mode 100644 product/pc/src/main/resources/base/element/string.json create mode 100644 product/pc/src/main/resources/base/media/icon.png create mode 100644 product/pc/src/main/resources/base/profile/main_pages.json create mode 100644 product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts create mode 100644 product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts create mode 100644 product/pc/src/ohosTest/ets/TestAbility/pages/index.ets create mode 100644 product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts create mode 100644 product/pc/src/ohosTest/ets/test/Ability.test.ets create mode 100644 product/pc/src/ohosTest/ets/test/List.test.ets create mode 100644 product/pc/src/ohosTest/module.json5 create mode 100644 product/pc/src/ohosTest/resources/base/element/color.json create mode 100644 product/pc/src/ohosTest/resources/base/element/string.json create mode 100644 product/pc/src/ohosTest/resources/base/media/icon.png create mode 100644 product/pc/src/ohosTest/resources/base/profile/test_pages.json create mode 100644 product/phone/.gitignore create mode 100644 product/phone/build-profile.json5 create mode 100644 product/phone/hvigorfile.js create mode 100644 product/phone/package-lock.json create mode 100644 product/phone/package.json create mode 100644 product/phone/src/main/ets/Application/MyAbilityStage.ts create mode 100644 product/phone/src/main/ets/MainAbility/MainAbility.ts create mode 100644 product/phone/src/main/ets/pages/Countdown.ets create mode 100644 product/phone/src/main/ets/pages/index.ets create mode 100644 product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets create mode 100644 product/phone/src/main/ets/pages/timer/TimeOfRecord.ets create mode 100644 product/phone/src/main/ets/pages/timer/Timer.ets create mode 100644 product/phone/src/main/ets/pages/timer/TimerClock.ets create mode 100644 product/phone/src/main/ets/pages/timer/TimerControl.ets create mode 100644 product/phone/src/main/module.json5 create mode 100644 product/phone/src/main/resources/base/element/float.json create mode 100644 product/phone/src/main/resources/base/element/string.json create mode 100644 product/phone/src/main/resources/base/media/icon.png create mode 100644 product/phone/src/main/resources/base/profile/main_pages.json create mode 100644 product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts create mode 100644 product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts create mode 100644 product/phone/src/ohosTest/ets/TestAbility/pages/index.ets create mode 100644 product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts create mode 100644 product/phone/src/ohosTest/ets/test/Ability.test.ets create mode 100644 product/phone/src/ohosTest/ets/test/List.test.ets create mode 100644 product/phone/src/ohosTest/module.json5 create mode 100644 product/phone/src/ohosTest/resources/base/element/color.json create mode 100644 product/phone/src/ohosTest/resources/base/element/string.json create mode 100644 product/phone/src/ohosTest/resources/base/media/icon.png create mode 100644 product/phone/src/ohosTest/resources/base/profile/test_pages.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..646ca11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/node_modules +/local.properties +**/local.properties +/.idea +**/build +/.hvigor +.preview +*/.preview \ No newline at end of file diff --git a/AppScope/app.json5 b/AppScope/app.json5 new file mode 100644 index 0000000..97024c9 --- /dev/null +++ b/AppScope/app.json5 @@ -0,0 +1,11 @@ +{ + "app": { + "bundleName": "com.example.ohosclock", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "distributedNotificationEnabled": true + } +} diff --git a/AppScope/resources/base/element/string.json b/AppScope/resources/base/element/string.json new file mode 100644 index 0000000..5893c1f --- /dev/null +++ b/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "OhosClock" + } + ] +} diff --git a/AppScope/resources/base/media/app_icon.png b/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5af1e0d50a73f3cbd710198786dce64c7bf02d95 GIT binary patch literal 4155 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 FV1k!j!Z82< literal 0 HcmV?d00001 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 2ef5a76..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# applications_clock - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 48f86e2..3b12565 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,42 @@ -# applications_clock - -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +# 录音机应用 + +- [时钟应用](#时钟应用) + - [简介](#简介) + - [目录](#目录) + - [目录结构](#目录结构) + - [约束](#约束) + +## 简介 +时钟应用 可以实现秒表计时功能和倒计时功能。 +时钟应用 采用 扩展的TS语言(eTS)开发,主要的结构如下: +![](./figures/clock.png) +- **product** + 业务形态层:区分不同产品、不同屏幕的各形态应用,含有个性化业务,组件的配置,以及个性化资源包。 + +- **feature** + 公共特性层:抽象的公共特性组件集合,可以被各应用形态引用。 + +- **common** + 公共能力层:基础能力集,每个应用形态都必须依赖的模块。 + +## 目录 +### 目录结构 +``` +/compass/ +├── common # 公共能力层目录 +├── feature # 公共特性层目录 +│ ├── countdown # 倒计时功能目录 +│ │ └── components # 倒计时组件目录 +│ │ └── controller # 倒计时控制逻辑目录 +│ └── timer # 秒表功能目录 +│ └── components # 秒表组件目录 +│ └── controller # 秒表控制逻辑目录 +├── product # 业务形态层目录 +``` +## 约束 +- 开发环境 + - **DevEco Studio for OpenHarmony**: 版本号大于3.0.0.992,下载安装OpenHarmony SDK API Version 9。(初始的IDE配置可以参考IDE的使用文档) +- 语言版本 + - eTS +- 限制 + - 本示例仅支持标准系统上运行 \ No newline at end of file diff --git a/build-profile.json5 b/build-profile.json5 new file mode 100644 index 0000000..8d28a9a --- /dev/null +++ b/build-profile.json5 @@ -0,0 +1,52 @@ +{ + "app": { + "signingConfigs": [ + ], + "compileSdkVersion": 9, + "compatibleSdkVersion": 9, + "products": [ + { + "name": "default", + "signingConfig": "default", + } + ] + }, + "modules": [ + { + "name": "pc", + "srcPath": "./product/pc", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "phone", + "srcPath": "./product/phone", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "common", + "srcPath": "./common" + }, + { + "name": "timer", + "srcPath": "./feature/timer" + }, + { + "name": "countdown", + "srcPath": "./feature/countdown" + } + ] +} \ No newline at end of file diff --git a/common/.gitignore b/common/.gitignore new file mode 100644 index 0000000..4f9a973 --- /dev/null +++ b/common/.gitignore @@ -0,0 +1,3 @@ +/node_modules +/.preview +/build \ No newline at end of file diff --git a/common/build-profile.json5 b/common/build-profile.json5 new file mode 100644 index 0000000..35dff6d --- /dev/null +++ b/common/build-profile.json5 @@ -0,0 +1,5 @@ +{ + "apiType": "stageMode", + "buildOption": { + } +} diff --git a/common/hvigorfile.js b/common/hvigorfile.js new file mode 100644 index 0000000..42ed4b4 --- /dev/null +++ b/common/hvigorfile.js @@ -0,0 +1,3 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +module.exports = require('@ohos/hvigor-ohos-plugin').harTasks + diff --git a/common/index.ets b/common/index.ets new file mode 100644 index 0000000..2587a53 --- /dev/null +++ b/common/index.ets @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { ImageComponent } from './src/main/ets/components/imageComponent' + +export { default as ConfigData } from './src/main/ets/utils/ConfigData' + +export { default as TimerUtil } from './src/main/ets/utils/TimerUtil' + +export { default as LogUtil } from './src/main/ets/utils/LogUtil' diff --git a/common/package-lock.json b/common/package-lock.json new file mode 100644 index 0000000..01b613f --- /dev/null +++ b/common/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "@ohos/common", + "version": "1.0.0", + "lockfileVersion": 1 +} diff --git a/common/package.json b/common/package.json new file mode 100644 index 0000000..6845131 --- /dev/null +++ b/common/package.json @@ -0,0 +1,14 @@ +{ + "license": "ISC", + "types": "", + "devDependencies": {}, + "name": "@ohos/common", + "description": "a npm package which contains arkUI2.0 page", + "ohos": { + "org": "" + }, + "main": "src/main/ets/components/MainPage/MainPage.ets", + "repository": {}, + "version": "1.0.0", + "dependencies": {} +} diff --git a/common/src/main/ets/components/imageComponent.ets b/common/src/main/ets/components/imageComponent.ets new file mode 100644 index 0000000..23e2f81 --- /dev/null +++ b/common/src/main/ets/components/imageComponent.ets @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Component +export struct ImageComponent { + private color: ResourceStr = ''; + @State imageSrc: ResourceStr = ''; + private imgLength: number = 32 + + build() { + Stack() { + Circle() + .width(this.imgLength * 2) + .height(this.imgLength * 2) + .fill(this.color) + Image(this.imageSrc).height(this.imgLength).width(this.imgLength) + } + } +} \ No newline at end of file diff --git a/common/src/main/ets/utils/ConfigData.ets b/common/src/main/ets/utils/ConfigData.ets new file mode 100644 index 0000000..f4f3b5e --- /dev/null +++ b/common/src/main/ets/utils/ConfigData.ets @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class ConfigData { + ONE_SECOND_TIME = 1000; + ONE_MINUTE_TIME = 60000; + ONE_HOUR_TIME = 3600000; + ONE_DAY_TIME = 86400000; + SCALE_NUM = 120; + COLOR_R = 98; + COLOR_G_START = 175; + COLOR_G_END = 125; + COLOR_B = 255; + HOUR_SELECT = 100; + MINUTE_SELECT = 60; + SECOND_SELECT = 60; + FONT_WEIGHT = 500; + NOTIFY_INTERVAL_MS = 50; + STANDARD_SIZE = 280; + DIALS_CENTER_OFFSET_X = 1 / 2; + MINUTE_DIALS_CENTER_OFFSET_Y = 5 / 16; + SECOND_DIALS_CENTER_OFFSET_Y = 1 / 2; + SHADOW_RADIUS = 20; + CIRCLE_WIDTH_COLOR = '#FFFFFF'; + SECOND_HAND_COLOR = '#007DFF'; + TICK_MARK_COLOR = '#66182431'; + HOUR_TICK_MARK_COLOR = '#22182431'; + TICK_MARK_WIDTH = 2; + HOUR_TICK_MARK_WIDTH = 4; + SECOND_DISTANCE = 5; + SECOND_POINTER_OVER = 12; + SECOND_CIRCLE_WIDTH = 6; + SECOND_FONT_SIZE = 16; + SECOND_HAND_WIDTH = 2; + SECOND_TICK_MARK_DISTANCE = 12; + HOUR_SECOND_TICK_MARK_DISTANCE = 16; + HOUR_SECOND_TIMER_DISTANCE = 28; + MINUTE_DISTANCE = 1; + MINUTE_TICK_MARK_WIDTH = 1.5; + MINUTE_TICK_MARK_DISTANCE = 6; + MINUTE_POINTER_DISTANCE = 20; + MINUTE_CIRCLE_WIDTH = 4; + MINUTE_CENTER_CIRCLE_WIDTH = 2.5; + MINUTE_FONT_SIZE = 12; + HOUR_MINUTE_TIMER_DISTANCE = 14; + WH_100_100 = '100%'; + WH_33_100 = '33%'; +} + +let configData = new ConfigData(); + +export default configData as ConfigData; \ No newline at end of file diff --git a/common/src/main/ets/utils/LogUtil.ts b/common/src/main/ets/utils/LogUtil.ts new file mode 100644 index 0000000..054bcfc --- /dev/null +++ b/common/src/main/ets/utils/LogUtil.ts @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import HiLog from "@ohos.hilog" + +const DOMAIN = 0x0500; +const TAG = "[Clock]" + +/** + * log package tool class + */ +export class LogUtil { + debug(msg): void { + HiLog.debug(DOMAIN, TAG, msg); + } + + log(msg): void { + HiLog.info(DOMAIN, TAG, msg); + } + + info(msg): void { + HiLog.info(DOMAIN, TAG, msg); + } + + warn(msg): void { + HiLog.warn(DOMAIN, TAG, msg); + } + + error(msg): void { + HiLog.error(DOMAIN, TAG, msg); + } +} + +let mLogUtil = new LogUtil(); + +export default mLogUtil as LogUtil +; \ No newline at end of file diff --git a/common/src/main/ets/utils/TimerUtil.ets b/common/src/main/ets/utils/TimerUtil.ets new file mode 100644 index 0000000..42e7da0 --- /dev/null +++ b/common/src/main/ets/utils/TimerUtil.ets @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import ConfigData from "./ConfigData" + +export class TimerUtil { + /** + * Time format conversion + * @param timestamp + */ + timeFormat(timestamp: number) { + if (timestamp <= 0) { + return "00:00.00" + } + let timeStr = "" + let day = Math.floor(timestamp / ConfigData.ONE_DAY_TIME) + if (day > 0) { + timeStr += this.addZero(day) + ":" + } + let hour = Math.floor(timestamp % ConfigData.ONE_DAY_TIME / ConfigData.ONE_HOUR_TIME) + if (hour > 0 || day > 0) { + timeStr += this.addZero(hour) + ":" + } + let min = Math.floor(timestamp % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME) + timeStr += this.addZero(min) + ":" + let sec = Math.floor(timestamp % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME) + timeStr += this.addZero(sec) + "." + let mSec = Math.floor(timestamp % ConfigData.ONE_SECOND_TIME / 10) + timeStr += this.addZero(mSec) + return timeStr + } + + /** + * If the number is less than 10, add "0". + * @param num + */ + addZero(num) { + return (num < 10 ? "0" + num : num).toString() + } +} + +let mTimerUtil = new TimerUtil() + +export default mTimerUtil as TimerUtil \ No newline at end of file diff --git a/common/src/main/module.json5 b/common/src/main/module.json5 new file mode 100644 index 0000000..56a91a8 --- /dev/null +++ b/common/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "common", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ], + "uiSyntax": "ets" + } +} diff --git a/common/src/main/resources/base/element/color.json b/common/src/main/resources/base/element/color.json new file mode 100644 index 0000000..2176617 --- /dev/null +++ b/common/src/main/resources/base/element/color.json @@ -0,0 +1,24 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + }, + { + "name": "background_color", + "value": "#F1F3F5" + }, + { + "name": "background_color_white", + "value": "#FFFFFF" + }, + { + "name": "text_color", + "value": "#182431" + }, + { + "name": "selected_text_color", + "value": "#007DFF" + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/base/element/string.json b/common/src/main/resources/base/element/string.json new file mode 100644 index 0000000..518dfe5 --- /dev/null +++ b/common/src/main/resources/base/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + }, + { + "name": "alarm_clock", + "value": "闹钟" + }, + { + "name": "stopwatch", + "value": "秒表" + }, + { + "name": "timer_clock", + "value": "计时器" + } + ] +} diff --git a/common/src/main/resources/base/media/ic_clock_clock.svg b/common/src/main/resources/base/media/ic_clock_clock.svg new file mode 100644 index 0000000..56d6316 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_clock.svg @@ -0,0 +1,12 @@ + + + ic_clock_clock + + + + + + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_clock_click.svg b/common/src/main/resources/base/media/ic_clock_clock_click.svg new file mode 100644 index 0000000..9249e36 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_clock_click.svg @@ -0,0 +1,12 @@ + + + ic_clock_clock_click + + + + + + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_play.svg b/common/src/main/resources/base/media/ic_clock_play.svg new file mode 100644 index 0000000..f6523b4 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_play.svg @@ -0,0 +1,7 @@ + + + ic_clock_play + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_refresh.svg b/common/src/main/resources/base/media/ic_clock_refresh.svg new file mode 100644 index 0000000..1ac9e87 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_refresh.svg @@ -0,0 +1,7 @@ + + + ic_clock_refresh备份 + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_second_chronograph.svg b/common/src/main/resources/base/media/ic_clock_second_chronograph.svg new file mode 100644 index 0000000..ed3c6e3 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_second_chronograph.svg @@ -0,0 +1,9 @@ + + + ic_clock_second chronograph + + + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_second_chronograph_click.svg b/common/src/main/resources/base/media/ic_clock_second_chronograph_click.svg new file mode 100644 index 0000000..e134bcc --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_second_chronograph_click.svg @@ -0,0 +1,9 @@ + + + ic_clock_second chronograph_click + + + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_sound.svg b/common/src/main/resources/base/media/ic_clock_sound.svg new file mode 100644 index 0000000..9cd82f5 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_sound.svg @@ -0,0 +1,7 @@ + + + ic_clock_sound + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_suspend.svg b/common/src/main/resources/base/media/ic_clock_suspend.svg new file mode 100644 index 0000000..2eeb22a --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_suspend.svg @@ -0,0 +1,8 @@ + + + ic_clock_suspend + + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_timer.svg b/common/src/main/resources/base/media/ic_clock_timer.svg new file mode 100644 index 0000000..f6e87f8 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_timer.svg @@ -0,0 +1,10 @@ + + + ic_clock_timer + + + + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_timer2.svg b/common/src/main/resources/base/media/ic_clock_timer2.svg new file mode 100644 index 0000000..497fdda --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_timer2.svg @@ -0,0 +1,10 @@ + + + ic_clock_timer2备份 + + + + + + + \ No newline at end of file diff --git a/common/src/main/resources/base/media/ic_clock_timer_click.svg b/common/src/main/resources/base/media/ic_clock_timer_click.svg new file mode 100644 index 0000000..63b8090 --- /dev/null +++ b/common/src/main/resources/base/media/ic_clock_timer_click.svg @@ -0,0 +1,10 @@ + + + ic_clock_timer_click + + + + + + + \ No newline at end of file diff --git a/feature/countdown/.gitignore b/feature/countdown/.gitignore new file mode 100644 index 0000000..4f9a973 --- /dev/null +++ b/feature/countdown/.gitignore @@ -0,0 +1,3 @@ +/node_modules +/.preview +/build \ No newline at end of file diff --git a/feature/countdown/build-profile.json5 b/feature/countdown/build-profile.json5 new file mode 100644 index 0000000..35dff6d --- /dev/null +++ b/feature/countdown/build-profile.json5 @@ -0,0 +1,5 @@ +{ + "apiType": "stageMode", + "buildOption": { + } +} diff --git a/feature/countdown/hvigorfile.js b/feature/countdown/hvigorfile.js new file mode 100644 index 0000000..42ed4b4 --- /dev/null +++ b/feature/countdown/hvigorfile.js @@ -0,0 +1,3 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +module.exports = require('@ohos/hvigor-ohos-plugin').harTasks + diff --git a/feature/countdown/index.ets b/feature/countdown/index.ets new file mode 100644 index 0000000..ab64a86 --- /dev/null +++ b/feature/countdown/index.ets @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { CountdownView } from './src/main/ets/components/CountdownView' + +export { TimeSelectView } from './src/main/ets/components/TimeSelectView' + +export { CountdownController, CountdownState } from './src/main/ets/controller/CountdownController' \ No newline at end of file diff --git a/feature/countdown/package-lock.json b/feature/countdown/package-lock.json new file mode 100644 index 0000000..2de3a00 --- /dev/null +++ b/feature/countdown/package-lock.json @@ -0,0 +1,11 @@ +{ + "name": "@ohos/countdown", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ohos/common": { + "version": "file:../../common" + } + } +} diff --git a/feature/countdown/package.json b/feature/countdown/package.json new file mode 100644 index 0000000..ad31594 --- /dev/null +++ b/feature/countdown/package.json @@ -0,0 +1,16 @@ +{ + "license": "ISC", + "types": "", + "devDependencies": {}, + "name": "@ohos/countdown", + "description": "a npm package which contains arkUI2.0 page", + "ohos": { + "org": "" + }, + "main": "src/main/ets/components/MainPage/MainPage.ets", + "repository": {}, + "version": "1.0.0", + "dependencies": { + "@ohos/common": "file:../../common" + } +} diff --git a/feature/countdown/src/main/ets/components/CountdownView.ets b/feature/countdown/src/main/ets/components/CountdownView.ets new file mode 100644 index 0000000..3e188db --- /dev/null +++ b/feature/countdown/src/main/ets/components/CountdownView.ets @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { CountdownState } from '../controller/CountdownController' +import { ConfigData } from '@ohos/common' + +@Component +export struct CountdownView { + private viewSize: number = 40 + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) + @Prop totalTime: number + @Prop currentTime: number + @State state: CountdownState = CountdownState.IDLE + private normalColor: string = '#007DFF' + private originRadius: number = 8 + private shadowOffset: number = 2.5 + private shadowColor: string = '#1400001E' + private scaleWidth: number = 2.5 + private scaleHeight: number = 16 + private scalePadding: number = 10.5 + private pointerOffset: number = 13.5 + + /** + * Draw CountdownView. + */ + private draw(): void{ + this.context.clearRect(0, 0, this.viewSize, this.viewSize) + + this.drawDials() + this.drawPointer(this.totalTime, this.currentTime) + } + + /** + * Draw origin circle and tick marks. + */ + private drawDials(): void{ + this.context.save() + this.context.beginPath() + this.context.fillStyle = this.normalColor + this.context.arc(this.viewSize / 2, this.viewSize / 2, this.originRadius, 0, Math.PI * 2) + this.context.fill() + this.context.shadowBlur = this.originRadius * 2 + this.shadowOffset + this.context.shadowColor = this.shadowColor + this.context.restore() + + for (let n = 0; n < ConfigData.SCALE_NUM; n++) { + var theta = n * (Math.PI * 2) / ConfigData.SCALE_NUM + this.context.save() + this.context.lineWidth = this.scaleWidth + this.context.beginPath() + var x_move = (this.viewSize / 2 - this.scalePadding) * Math.sin(theta) + this.viewSize / 2 + var y_move = -(this.viewSize / 2 - this.scalePadding) * Math.cos(theta) + this.viewSize / 2 + var x_to = (this.viewSize / 2 - (this.scalePadding + this.scaleHeight)) * Math.sin(theta) + this.viewSize / 2 + var y_to = -(this.viewSize / 2 - (this.scalePadding + this.scaleHeight)) * Math.cos(theta) + this.viewSize / 2 + this.context.strokeStyle = + (this.state == CountdownState.RUNNING || this.state == CountdownState.PAUSED) && + (this.currentTime / this.totalTime > n / ConfigData.SCALE_NUM) && n ? + 'rgb(' + Math.ceil(ConfigData.COLOR_R - (ConfigData.COLOR_R / ConfigData.SCALE_NUM * n)) + ',' + + Math.ceil(ConfigData.COLOR_G_START - (ConfigData.COLOR_G_START - ConfigData.COLOR_G_END) / ConfigData.SCALE_NUM * n) + ',' + ConfigData.COLOR_B + ')' : + '#66182431' + this.context.moveTo(x_move, y_move) + this.context.lineTo(x_to, y_to) + this.context.stroke() + this.context.restore() + } + } + + /** + * Draw pointer. + */ + private drawPointer(totalTime: number, currentTime: number): void{ + this.context.save() + this.context.strokeStyle = this.normalColor + this.context.shadowBlur = this.scaleWidth + this.shadowOffset + this.context.shadowColor = this.shadowColor + var theta = totalTime ? currentTime / totalTime * Math.PI * 2 : 0 + this.context.beginPath() + this.context.lineWidth = this.scaleWidth + var x_move = (this.viewSize / 2 - this.scalePadding) * Math.sin(theta) + this.viewSize / 2 + var y_move = -(this.viewSize / 2 - this.scalePadding) * Math.cos(theta) + this.viewSize / 2 + var x_to = -(this.originRadius + this.pointerOffset) * Math.sin(theta) + this.viewSize / 2 + var y_to = (this.originRadius + this.pointerOffset) * Math.cos(theta) + this.viewSize / 2 + this.context.moveTo(x_move, y_move) + this.context.lineTo(x_to, y_to) + this.context.stroke() + this.context.restore() + } + + build() { + Canvas(this.context) + .width(this.viewSize) + .height(this.viewSize) + .backgroundColor($r("app.color.background_color_white")) + .border({ radius: this.viewSize }) + .shadow({ radius: $r("app.float.radius_value_26_5"), color: this.shadowColor }) + .onReady(() => { + this.draw() + }) + } +} \ No newline at end of file diff --git a/feature/countdown/src/main/ets/components/TimeSelectView.ets b/feature/countdown/src/main/ets/components/TimeSelectView.ets new file mode 100644 index 0000000..cc2f920 --- /dev/null +++ b/feature/countdown/src/main/ets/components/TimeSelectView.ets @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigData, LogUtil } from '@ohos/common' + +const TAG = "TimeSelectView : " + +@Component +export struct TimeSelectView { + private marginRight: number | Resource = $r("app.float.distance_30") + private dividerMargin: number | Resource = $r("app.float.distance_75") + private select: number = 0 + private hourRange: number[] = Array.from(new Array(ConfigData.HOUR_SELECT).keys()) + private minuteRange: number[] = Array.from(new Array(ConfigData.MINUTE_SELECT).keys()) + private secondRange: number[] = Array.from(new Array(ConfigData.SECOND_SELECT).keys()) + @Link hour: string + @Link minute: string + @Link second: string + private callBack?: () => void + private sca: number = 1 + + build() { + Flex({ justifyContent: FlexAlign.Center, alignContent: FlexAlign.Start }) { + Stack() { + Row() { + TimeSelectItem({ + fruits: this.convert(this.hourRange), + text: $r("app.string.hour"), + isVisibility: true, + marginRight: this.marginRight, + value: $hour, + onChangCallBack: this.callBack + }) + + TimeSelectItem({ + fruits: this.convert(this.minuteRange), + text: $r("app.string.minute"), + isVisibility: true, + marginRight: this.marginRight, + value: $minute, + onChangCallBack: this.callBack + }) + + TimeSelectItem({ + fruits: this.convert(this.secondRange), + text: $r("app.string.second"), + isVisibility: false, + marginRight: this.marginRight, + value: $second, + onChangCallBack: this.callBack + }) + } + + Divider() + .strokeWidth(1) + .color($r("app.color.divider_color")) + .margin({ left: this.dividerMargin, right: this.dividerMargin, top: $r("app.float.distance_35") }) + + Divider() + .strokeWidth(1) + .color($r("app.color.divider_color")) + .margin({ left: this.dividerMargin, right: this.dividerMargin, bottom: $r("app.float.distance_78") }) + } + } + .scale({ x: this.sca, y: this.sca }) + } + + /** + * Make up 0 if less than 10. + */ + private convert(char: Array) { + let str = [] + for (let i = 0; i < char.length; i++) { + str.push((char[i] > 9 ? "" : "0") + char[i]) + } + return str + } +} + +@Component +struct TimeSelectItem { + private fruits: string[] = [] + private select: number = 0 + private text: ResourceStr = '' + private isVisibility: boolean = true + private marginRight: number | Resource = $r("app.float.distance_30") + @Link value: string + private componentWidth: number | Resource = $r("app.float.wh_value_40") + private componentHeight: number | Resource = $r("app.float.wh_value_160") + private onChangCallBack?: () => void + + build() { + Row() { + Column() { + TextPicker({ range: this.fruits, selected: Number(this.value) }) + .backgroundColor($r("app.color.background_color")) + .width(this.componentWidth) + .height(this.componentHeight) + .onChange((value: string, index: number) => { + this.value = value + this.onChangCallBack() + LogUtil.info(`${TAG} Picker item changed, value: ${value}, index: ${index} `) + }) + Text(this.text).fontSize($r("app.float.font_24")).fontWeight(ConfigData.FONT_WEIGHT).height($r("app.float.wh_value_21_5")) + }.margin({ right: this.isVisibility ? this.marginRight : $r("app.float.distance_0") }) + + Column() { + Text(":").fontSize($r("app.float.font_40")).fontWeight(ConfigData.FONT_WEIGHT).fontColor($r("app.color.font_color")) + Text("").fontSize($r("app.float.font_24")).fontWeight(ConfigData.FONT_WEIGHT).height($r("app.float.wh_value_21_5")) + }.margin({ right: this.marginRight }) + .visibility(this.isVisibility ? Visibility.Visible : Visibility.None) + } + } +} \ No newline at end of file diff --git a/feature/countdown/src/main/ets/controller/CountdownController.ets b/feature/countdown/src/main/ets/controller/CountdownController.ets new file mode 100644 index 0000000..a702b32 --- /dev/null +++ b/feature/countdown/src/main/ets/controller/CountdownController.ets @@ -0,0 +1,271 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import dataStorage from '@ohos.data.preferences'; +import { ConfigData, LogUtil } from '@ohos/common' + +const TAG = "CountdownController : " + +export enum CountdownState { + /** + * The total time in the initial state is not set. The default is 0, but can be triggered by the reset() method or PREPARED to set it to 0 + */ + IDLE, + + /** + * Set the legal time (positive number) at this time to cancel the ash can click Start + */ + PREPARED, + + /** + * Continuously update the time starting from click on PREPARE or PAUSED + */ + RUNNING, + + /** + * Click Pause from the RUNNING state + */ + PAUSED, + + /** + * RUNNING status Automatically transitions to STOPPED when the countdown ends. This state is not triggered externally + */ + STOPPED +} + +export class CountdownController { + private totalTimeMs: number = 0; + private currentTimeMs: number = 0; + private notifierId: number = 0; + private startTimestamp: number = 0; + private startAnchorTimeMs: number = 0; + state: CountdownState = CountdownState.IDLE; + timeUpdateListener: (currentTimeMs: number, totalTimeMs: number) => void = undefined + stateUpdateListener: (CountdownState) => void = undefined; + private preferences = null; + + /** + * Set time listener. + */ + setTimeUpdateListener(listener: (currentTimeMs: number, totalTimeMs: number) => void) { + this.timeUpdateListener = listener; + } + + /** + * Set countdownState listener. + */ + setStateUpdateListener(listener: (CountdownState) => void) { + this.stateUpdateListener = listener; + } + + /** + * Set countdown time. + */ + setTime(totalTimeMs: number) { + LogUtil.info(`${TAG} set countdown time. `) + if (this.state != CountdownState.IDLE && this.state != CountdownState.PREPARED) { + throw ('only support set time before start!') + } + if (totalTimeMs < 0) { + throw ('illegal totalTimeMs!') + } + this.totalTimeMs = totalTimeMs; + LogUtil.info(`${TAG} countdown totalTime: ${this.totalTimeMs}ms. `) + this.startAnchorTimeMs = this.totalTimeMs; + this.updateData('totalTimeMs', this.totalTimeMs); + this.updateData('startAnchorTimeMs', this.startAnchorTimeMs); + this.currentTimeMs = totalTimeMs; + this.notifyTimeChanges() + if (this.state == CountdownState.IDLE && totalTimeMs > 0) { + this.state = CountdownState.PREPARED + this.updateData('CountdownState', this.state); + this.notifyStateChanges(); + } else if (this.state == CountdownState.PREPARED && totalTimeMs == 0) { + this.state = CountdownState.IDLE + this.updateData('CountdownState', this.state); + this.notifyStateChanges(); + } + } + + private notifyTimeChanges() { + if (this.timeUpdateListener) { + this.timeUpdateListener(this.currentTimeMs, this.totalTimeMs) + } + } + + private notifyStateChanges() { + if (this.stateUpdateListener) { + this.stateUpdateListener(this.state) + } + } + + /** + * Countdown start. + */ + start() { + LogUtil.info(`${TAG} countdown start. `) + if (this.state != CountdownState.PREPARED && this.state != CountdownState.PAUSED) { + return; + } + LogUtil.info(`${TAG} countdown start in. `) + if (this.totalTimeMs > 0 && this.currentTimeMs > 0) { + if (this.currentTimeMs >= ConfigData.NOTIFY_INTERVAL_MS) { + this.startTimestamp = new Date().getTime(); + this.updateData('startTimestamp', this.startTimestamp); + this.countdown(); + } else { + this.lastRefresh(); + } + } + this.state = CountdownState.RUNNING; + this.updateData('CountdownState', this.state); + this.notifyStateChanges() + } + + /** + * Countdown start-up. + */ + countdown() { + LogUtil.info(`${TAG} countdown start up. `) + this.notifierId = setInterval(() => { + let timestamp = new Date().getTime(); + this.currentTimeMs = this.startAnchorTimeMs - (timestamp - this.startTimestamp) + if (this.currentTimeMs <= 0) { + this.currentTimeMs = 0; + clearInterval(this.notifierId) + this.notifierId = 0 + } else if (this.currentTimeMs < ConfigData.NOTIFY_INTERVAL_MS) { + clearInterval(this.notifierId) + this.notifierId = 0 + this.lastRefresh(); + } + this.notifyTimeChanges() + if (this.currentTimeMs == 0) { + this.state = CountdownState.STOPPED + this.updateData('CountdownState', this.state); + this.notifyStateChanges() + } + }, ConfigData.NOTIFY_INTERVAL_MS) + } + + /** + * Countdown reStart. + */ + reStart() { + LogUtil.info(`${TAG} countdown reStart. `) + if (this.state == CountdownState.STOPPED) { + this.state = CountdownState.PREPARED + this.updateData('CountdownState', this.state); + this.notifyStateChanges() + } + } + + /** + * Countdown lastRefresh. + */ + lastRefresh() { + LogUtil.info(`${TAG} countdown lastRefresh. `) + setTimeout(() => { + this.currentTimeMs = 0; + this.notifyTimeChanges() + this.state = CountdownState.STOPPED + this.updateData('CountdownState', this.state); + this.notifyStateChanges() + }, this.currentTimeMs) + } + + /** + * Countdown pause. + */ + pause() { + LogUtil.info(`${TAG} countdown pause. `) + if (this.state != CountdownState.RUNNING) { + return; + } + LogUtil.info(`${TAG} countdown pause in. `) + let timestamp = new Date().getTime(); + clearInterval(this.notifierId); + this.startAnchorTimeMs = this.startAnchorTimeMs - (timestamp - this.startTimestamp) + this.updateData('startAnchorTimeMs', this.startAnchorTimeMs); + this.notifierId = 0; + this.state = CountdownState.PAUSED; + this.updateData('CountdownState', this.state); + this.notifyStateChanges() + } + + /** + * Countdown reset. + */ + reset() { + LogUtil.info(`${TAG} countdown reset. `) + if (this.state == CountdownState.IDLE) { + return; + } + LogUtil.info(`${TAG} countdown reset in. `) + if (this.notifierId != 0) { + clearInterval(this.notifierId) + this.notifierId = 0; + } + this.totalTimeMs = 0 + this.updateData('totalTimeMs', this.totalTimeMs); + this.currentTimeMs = 0 + this.startTimestamp = 0; + this.updateData('startTimestamp', this.startTimestamp); + this.startAnchorTimeMs = 0; + this.notifyTimeChanges(); + this.state = CountdownState.IDLE + this.updateData('CountdownState', this.state); + this.notifyStateChanges() + } + + /** + * Get preferences data. + */ + public async getPreferences() { + if (this.preferences) { + this.preferences = await dataStorage.getPreferences(globalThis.abilityContext, 'Countdown'); + } + } + + /** + * Instance matching a specified preferences file name. + */ + public async getData() { + await this.getPreferences(); + this.state = await this.preferences.get('CountdownState', CountdownState.IDLE); + this.startTimestamp = await this.preferences.get('startTimestamp', 0); + this.totalTimeMs = await this.preferences.get('totalTimeMs', 0); + this.startAnchorTimeMs = await this.preferences.get('startAnchorTimeMs', 0); + + if (this.state == CountdownState.PREPARED) { + this.currentTimeMs = this.totalTimeMs; + } else if (this.state == CountdownState.RUNNING) { + this.countdown(); + } else if (this.state == CountdownState.PAUSED) { + this.currentTimeMs = this.startAnchorTimeMs + } + this.notifyStateChanges(); + this.notifyTimeChanges(); + } + + /** + * Put and flush preferences data. + */ + public async updateData(key: string, defValue: string | number) { + if (this.preferences) { + await this.preferences.put(key, defValue); + await this.preferences.flush(); + } + } +} \ No newline at end of file diff --git a/feature/countdown/src/main/module.json5 b/feature/countdown/src/main/module.json5 new file mode 100644 index 0000000..aeb2939 --- /dev/null +++ b/feature/countdown/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "countdown", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ], + "uiSyntax": "ets" + } +} diff --git a/feature/countdown/src/main/resources/base/element/color.json b/feature/countdown/src/main/resources/base/element/color.json new file mode 100644 index 0000000..240a3f9 --- /dev/null +++ b/feature/countdown/src/main/resources/base/element/color.json @@ -0,0 +1,20 @@ +{ + "color": [ + { + "name": "background_color_white", + "value": "#FFFFFF" + }, + { + "name": "background_color", + "value": "#f1f3f5" + }, + { + "name": "divider_color", + "value": "#000000" + }, + { + "name": "font_color", + "value": "#2B78FB" + } + ] +} \ No newline at end of file diff --git a/feature/countdown/src/main/resources/base/element/float.json b/feature/countdown/src/main/resources/base/element/float.json new file mode 100644 index 0000000..abe9f37 --- /dev/null +++ b/feature/countdown/src/main/resources/base/element/float.json @@ -0,0 +1,48 @@ +{ + "float": [ + { + "name": "wh_value_21_5", + "value": "21.5vp" + }, + { + "name": "wh_value_40", + "value": "40vp" + }, + { + "name": "wh_value_160", + "value": "160vp" + }, + { + "name": "radius_value_26_5", + "value": "26.5vp" + }, + { + "name": "font_24", + "value": "24px" + }, + { + "name": "font_40", + "value": "40px" + }, + { + "name": "distance_0", + "value": "0vp" + }, + { + "name": "distance_30", + "value": "30vp" + }, + { + "name": "distance_35", + "value": "35vp" + }, + { + "name": "distance_75", + "value": "75vp" + }, + { + "name": "distance_78", + "value": "78vp" + } + ] +} \ No newline at end of file diff --git a/feature/countdown/src/main/resources/base/element/string.json b/feature/countdown/src/main/resources/base/element/string.json new file mode 100644 index 0000000..f2810e5 --- /dev/null +++ b/feature/countdown/src/main/resources/base/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + }, + { + "name": "hour", + "value": "时" + }, + { + "name": "minute", + "value": "分" + }, + { + "name": "second", + "value": "秒" + } + ] +} diff --git a/feature/timer/.gitignore b/feature/timer/.gitignore new file mode 100644 index 0000000..4f9a973 --- /dev/null +++ b/feature/timer/.gitignore @@ -0,0 +1,3 @@ +/node_modules +/.preview +/build \ No newline at end of file diff --git a/feature/timer/build-profile.json5 b/feature/timer/build-profile.json5 new file mode 100644 index 0000000..35dff6d --- /dev/null +++ b/feature/timer/build-profile.json5 @@ -0,0 +1,5 @@ +{ + "apiType": "stageMode", + "buildOption": { + } +} diff --git a/feature/timer/hvigorfile.js b/feature/timer/hvigorfile.js new file mode 100644 index 0000000..42ed4b4 --- /dev/null +++ b/feature/timer/hvigorfile.js @@ -0,0 +1,3 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +module.exports = require('@ohos/hvigor-ohos-plugin').harTasks + diff --git a/feature/timer/index.ets b/feature/timer/index.ets new file mode 100644 index 0000000..95bd1ed --- /dev/null +++ b/feature/timer/index.ets @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { TimerView } from './src/main/ets/components/TimerView' + +export { TimerController, TimerState } from './src/main/ets/controller/TimerController' diff --git a/feature/timer/package-lock.json b/feature/timer/package-lock.json new file mode 100644 index 0000000..e693da1 --- /dev/null +++ b/feature/timer/package-lock.json @@ -0,0 +1,11 @@ +{ + "name": "@ohos/timer", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ohos/common": { + "version": "file:../../common" + } + } +} diff --git a/feature/timer/package.json b/feature/timer/package.json new file mode 100644 index 0000000..811bb31 --- /dev/null +++ b/feature/timer/package.json @@ -0,0 +1,16 @@ +{ + "license": "ISC", + "types": "", + "devDependencies": {}, + "name": "@ohos/timer", + "description": "a npm package which contains arkUI2.0 page", + "ohos": { + "org": "" + }, + "main": "src/main/ets/components/MainPage/MainPage.ets", + "repository": {}, + "version": "1.0.0", + "dependencies": { + "@ohos/common": "file:../../common" + } +} diff --git a/feature/timer/src/main/ets/components/TimerView.ets b/feature/timer/src/main/ets/components/TimerView.ets new file mode 100644 index 0000000..3aa694e --- /dev/null +++ b/feature/timer/src/main/ets/components/TimerView.ets @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http:// www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigData } from '@ohos/common' + +@Component +export struct TimerView { + private sSize: number = vp2px(ConfigData.STANDARD_SIZE) + @Prop currentTime: number + private mSize: number = 0 + private dialsContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) + private secondContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) + private minutesContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) + // Second disc radius + private sRadius: number = 0 + // Points set radius + private mRadius: number = 0 + // scale + private mScale: number = 1 + // Second hand time scale value + private times: Array = [60, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,] + // Minute hand time scale value + private minTimes: Array = [30, 5, 10, 15, 20, 25] + + aboutToAppear() { + this.mScale = this.sSize / ConfigData.STANDARD_SIZE + this.mSize = this.sSize / 4 + // Get the radius + this.sRadius = this.sSize / 2 - ConfigData.SECOND_DISTANCE * this.mScale + this.mRadius = this.mSize / 2 - ConfigData.MINUTE_DISTANCE * this.mScale + } + + build() { + Row() { + Stack() { + Canvas(this.dialsContext) + .height(this.sSize) + .aspectRatio(1.0) + .onReady(() => { + this.drawDials() + }) + .backgroundColor($r("app.color.background_color_white")) + .borderRadius(this.sSize / 2) + .shadow({ radius: ConfigData.SHADOW_RADIUS * this.mScale, color: $r("app.color.shadow_color") }) + Canvas(this.minutesContext) + .height(this.sSize) + .aspectRatio(1.0) + .onReady(() => { + this.drawMinutes(this.currentTime % (60 * 60 * 1000) / (60 * 1000)) + }) + Canvas(this.secondContext) + .height(this.sSize) + .aspectRatio(1.0) + .onReady(() => { + this.drawSecond(this.currentTime % (60 * 1000) / 1000) + }) + } + } + .justifyContent(FlexAlign.Center) + .width(ConfigData.WH_100_100) + } + + /** + * Draw a Second hand + * @param second + */ + private drawSecond(second: number): void{ + this.secondContext.clearRect(0, 0, this.sSize, this.sSize) + this.secondContext.lineCap = 'round' + this.secondContext.save() + this.secondContext.strokeStyle = ConfigData.SECOND_HAND_COLOR + // Pointer Angle The second hand is divided into 60 parts + let theta = second * 2 * Math.PI / 60; + this.secondContext.beginPath() + // A pointer to draw + let x_move = this.sRadius * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_move = -this.sRadius * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; + let x_to = -(ConfigData.SECOND_POINTER_OVER * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_to = (ConfigData.SECOND_POINTER_OVER * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; + + this.secondContext.lineWidth = ConfigData.SECOND_HAND_WIDTH * this.mScale + this.secondContext.moveTo(x_move, y_move); + this.secondContext.lineTo(x_to, y_to); + this.secondContext.stroke(); + this.secondContext.restore(); + } + + /** + * Draw a minute hand + * @param minutes + */ + private drawMinutes(minutes: number): void{ + this.minutesContext.clearRect(0, 0, this.sSize, this.sSize) + this.minutesContext.lineCap = 'round' + this.minutesContext.save() + // Pointer Angle The minute hand is divided into 30 parts + let theta = minutes * 2 * Math.PI / 30; + this.minutesContext.beginPath() + // Start position of scale + let x_move = (this.mRadius - ConfigData.MINUTE_POINTER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_move = -(this.mRadius - ConfigData.MINUTE_POINTER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; + // End of scale position + let x_to = (ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_to = (-ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; + this.minutesContext.lineWidth = ConfigData.MINUTE_TICK_MARK_WIDTH * this.mScale + this.minutesContext.moveTo(x_move, y_move); + this.minutesContext.lineTo(x_to, y_to); + this.minutesContext.stroke(); + this.minutesContext.restore(); + } + + private drawDials() { + this.dialsContext.clearRect(0, 0, this.sSize, this.sSize) + this.drawSecDials() + this.drawMinDials() + } + + /** + * Draw the second hand disc + */ + private drawSecDials(): void{ + this.dialsContext.lineCap = 'round' + // Draw the origin + this.dialsContext.save() + this.dialsContext.fillStyle = ConfigData.SECOND_HAND_COLOR + this.dialsContext.beginPath() + + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y, ConfigData.SECOND_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2) + this.dialsContext.fill() + this.dialsContext.restore() + this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR + // Font style + this.dialsContext.font = "normal 500 " + vp2px(ConfigData.SECOND_FONT_SIZE * this.mScale) + 'px' + this.dialsContext.textBaseline = "middle" + this.dialsContext.textAlign = "center" + // Drawing scale + for (let n = 0; n < 60; n++) { + // Gets an Angle of 60 scales + let theta = n * (Math.PI * 2) / 60; + this.dialsContext.save() + // Setting the scale width + this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale + this.dialsContext.beginPath() + // Start position of scale + let x_move = this.sRadius * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_move = -this.sRadius * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; + // End position of non - hour scale + let x_to = (this.sRadius - ConfigData.SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_to = -(this.sRadius - ConfigData.SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; + // Integral point calibration + if (n % 5 == 0) { + // The scale width of the hour + this.dialsContext.lineWidth = ConfigData.HOUR_TICK_MARK_WIDTH * this.mScale + // End position of the mark on the hour + x_to = (this.sRadius - ConfigData.HOUR_SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + y_to = -(this.sRadius - ConfigData.HOUR_SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; + // Time position on the hour + let x_time = (this.sRadius - ConfigData.HOUR_SECOND_TIMER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_time = -(this.sRadius - ConfigData.HOUR_SECOND_TIMER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; + // Plot the hour + this.dialsContext.fillText(this.times[n / 5] + '', x_time, y_time) + } + // Draw the scale + this.dialsContext.moveTo(x_move, y_move) + this.dialsContext.lineTo(x_to, y_to) + this.dialsContext.stroke() + this.dialsContext.restore() + } + } + + /** + * Draw the minute hand dial + */ + private drawMinDials(): void{ + // Draw the origin + this.dialsContext.save() + this.dialsContext.beginPath() + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2) + this.dialsContext.fill() + this.dialsContext.fillStyle = ConfigData.CIRCLE_WIDTH_COLOR + this.dialsContext.beginPath() + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CENTER_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2) + this.dialsContext.fill() + this.dialsContext.restore() + // Font style + this.dialsContext.font = "normal 400 " + vp2px(ConfigData.MINUTE_FONT_SIZE * this.mScale) + 'px' + // Drawing scale + for (let n = 0; n < 30; n++) { + this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR + let theta = n * (Math.PI * 2) / 30; + this.dialsContext.save() + // Scale width + this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale + this.dialsContext.beginPath() + // Start position of scale + let x_move = this.mRadius * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_move = -this.mRadius * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; + // End of scale position + let x_to = (this.mRadius - ConfigData.MINUTE_TICK_MARK_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_to = -(this.mRadius - ConfigData.MINUTE_TICK_MARK_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; + // Integral point calibration + if (n % 5 == 0) { + this.dialsContext.strokeStyle = ConfigData.HOUR_TICK_MARK_COLOR + // Time position on the hour + let x_time = (this.mRadius - ConfigData.HOUR_MINUTE_TIMER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; + let y_time = -(this.mRadius - ConfigData.HOUR_MINUTE_TIMER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; + // Plot the hour + this.dialsContext.fillText(this.minTimes[n / 5] + '', x_time, y_time) + } + // Draw the scale + this.dialsContext.moveTo(x_move, y_move) + this.dialsContext.lineTo(x_to, y_to) + this.dialsContext.stroke() + this.dialsContext.restore() + } + } +} diff --git a/feature/timer/src/main/ets/controller/TimerController.ets b/feature/timer/src/main/ets/controller/TimerController.ets new file mode 100644 index 0000000..34a2563 --- /dev/null +++ b/feature/timer/src/main/ets/controller/TimerController.ets @@ -0,0 +1,247 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigData, LogUtil } from '@ohos/common' +import data_preferences from '@ohos.data.preferences'; + +const TAG = "TimerController : " + +export enum TimerState { + /** + * The initial state + */ + IDLE, + /** + * Continuously update time starting from IDLE or PAUSED state + */ + RUNNING, + /** + * Click Pause from the RUNNING state + */ + PAUSED, +} + +export class TimerController { + private currentTimeMs: number = 0; + private beforePauseTime: number = 0 + private state: TimerState = TimerState.IDLE; + private startTimestamp: number = 0 + private notifierId: number = -1 + private timeList: Array = [] + private lastTimeMs: number = 0 + private timeUpdateListener: (currentTimeMs: number) => void = undefined + private clockUpdateListener: (currentTimeMs: number) => void = undefined + private stateUpdateListener: (TimerState) => void = undefined; + private timeListUpdateListener: (timeList: Array, lastTimeMs: number) => void = undefined; + private preferences: data_preferences.Preferences = undefined + + /** + * Timer start + */ + public async start() { + LogUtil.info(`${TAG} timer start `) + this.startTimestamp = new Date().getTime(); + if (this.notifierId != -1) { + clearInterval(this.notifierId) + this.notifierId = -1 + } + this.notifierId = setInterval(() => { + let timestamp = new Date().getTime(); + this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp + this.notifyTimeChanges() + }, ConfigData.NOTIFY_INTERVAL_MS) + if (this.preferences) { + await this.preferences.put("startTimestamp", this.startTimestamp) + } + this.state = TimerState.RUNNING; + this.notifyStateChanges() + } + + /** + * Timer pause + */ + public async pause() { + LogUtil.info(`${TAG} timer pause `) + clearInterval(this.notifierId) + this.beforePauseTime += new Date().getTime() - this.startTimestamp + this.currentTimeMs = this.beforePauseTime + this.notifyTimeChanges() + this.notifierId = -1 + this.state = TimerState.PAUSED; + if (this.preferences) { + await this.preferences.put("beforePauseTime", this.beforePauseTime) + } + this.notifyTimeChanges() + this.notifyStateChanges() + } + + /** + * Timer reset + */ + public reset() { + LogUtil.info(`${TAG} timer reset `) + this.beforePauseTime = 0 + this.startTimestamp = 0 + this.timeList = [] + this.lastTimeMs = 0 + this.notifierId = -1 + this.currentTimeMs = 0 + this.state = TimerState.IDLE; + this.notifyTimeChanges() + this.notifyStateChanges() + this.notifyTimeListChanges() + this.preferences.clear() + } + + /** + * Read the previous state from the preferences + */ + public async reload() { + LogUtil.info(`${TAG} Read the previous data `) + this.preferences = await data_preferences.getPreferences(globalThis.abilityContext, 'myClockStore') + this.state = await this.preferences.get("state", TimerState.IDLE) + this.lastTimeMs = await this.preferences.get("lastTimeMs", 0) + this.beforePauseTime = await this.preferences.get("beforePauseTime", 0) + this.startTimestamp = await this.preferences.get("startTimestamp", 0) + + let timeList = await this.preferences.get("timeList", 0) + if (timeList == 0) { + this.timeList = [] + } else { + this.timeList = > timeList + } + + if (this.state == TimerState.RUNNING) { + if (this.notifierId != -1) { + clearInterval(this.notifierId) + this.notifierId = -1 + } + this.notifierId = setInterval(() => { + let timestamp = new Date().getTime(); + this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp + this.notifyTimeChanges() + }, ConfigData.NOTIFY_INTERVAL_MS) + } else if (this.state == TimerState.PAUSED) { + this.currentTimeMs = this.beforePauseTime + } else { + this.reset() + } + this.notifyTimeChanges() + if (this.timeList.length > 0) { + this.notifyTimeListChanges() + } + this.notifyStateChanges() + } + + /** + * Recording the Current Time + */ + public writeTime() { + LogUtil.info(`${TAG} Recording time `) + let timestamp = new Date().getTime(); + this.lastTimeMs = Math.floor((this.beforePauseTime + timestamp - this.startTimestamp) / 10) * 10 + this.timeList.push(this.lastTimeMs) + this.notifyTimeListChanges() + } + + /** + * Notice time change + */ + private notifyTimeChanges() { + if (this.timeUpdateListener) { + this.timeUpdateListener(this.currentTimeMs) + } + if (this.clockUpdateListener) { + this.clockUpdateListener(this.currentTimeMs) + } + } + + /** + * Notifies record time list changes + */ + private async notifyTimeListChanges() { + if (this.timeListUpdateListener) { + this.timeListUpdateListener(this.timeList, this.lastTimeMs) + } + if (this.preferences) { + await this.preferences.put("timeList", this.timeList) + await this.preferences.put("lastTimeMs", this.lastTimeMs) + this.flush() + } + } + + /** + * Notification of status change + */ + private async notifyStateChanges() { + LogUtil.info(`${TAG} state update ${this.state}`) + if (this.stateUpdateListener) { + this.stateUpdateListener(this.state) + } + if (this.preferences) { + await this.preferences.put("state", this.state) + this.flush() + } + } + + /** + * Persist preferences + */ + private flush() { + this.preferences.flush(function (err) { + if (err) { + console.warn("Failed flush. Cause: " + err); + return; + } + console.warn("Succeeded flush."); + }) + } + + /** + * Set listening for state changes + * @param listener + */ + public setStateUpdateListener(listener: (TimerState) => void) { + LogUtil.info(`${TAG} setStateUpdateListener`) + this.stateUpdateListener = listener; + } + + /** + * Set time change listening + * @param listener + */ + public setTimeUpdateListener(listener: (currentTimeMs: number) => void) { + LogUtil.info(`${TAG} setTimeUpdateListener`) + this.timeUpdateListener = listener; + } + + /** + * Set time clock change listening + * @param listener + */ + public setClockUpdateListener(listener: (currentTimeMs: number) => void) { + LogUtil.info(`${TAG} setClockUpdateListener`) + this.clockUpdateListener = listener; + } + + /** + * Set the record time list change listening + * @param listener + */ + public setTimeListUpdateListener(listener: (timeList: Array, lastTimeMs: number) => void) { + LogUtil.info(`${TAG} setTimeListUpdateListener`) + this.timeListUpdateListener = listener; + } +} \ No newline at end of file diff --git a/feature/timer/src/main/module.json5 b/feature/timer/src/main/module.json5 new file mode 100644 index 0000000..9694f66 --- /dev/null +++ b/feature/timer/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "timer", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ], + "uiSyntax": "ets" + } +} diff --git a/feature/timer/src/main/resources/base/element/color.json b/feature/timer/src/main/resources/base/element/color.json new file mode 100644 index 0000000..e3eb225 --- /dev/null +++ b/feature/timer/src/main/resources/base/element/color.json @@ -0,0 +1,12 @@ +{ + "color": [ + { + "name": "background_color_white", + "value": "#FFFFFF" + }, + { + "name": "shadow_color", + "value": "#1400001E" + } + ] +} diff --git a/feature/timer/src/main/resources/base/element/string.json b/feature/timer/src/main/resources/base/element/string.json new file mode 100644 index 0000000..1e76de0 --- /dev/null +++ b/feature/timer/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/figures/clock.png b/figures/clock.png new file mode 100644 index 0000000000000000000000000000000000000000..3d677721f0595907e5542b0d9067e42a238cfa25 GIT binary patch literal 10250 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 { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + console.log("[Demo] MainAbility onWindowStageDestroy") + } + + onForeground() { + // Ability has brought to foreground + console.log("[Demo] MainAbility onForeground") + } + + onBackground() { + // Ability has back to background + console.log("[Demo] MainAbility onBackground") + } +}; diff --git a/product/pc/src/main/ets/pages/Countdown.ets b/product/pc/src/main/ets/pages/Countdown.ets new file mode 100644 index 0000000..479fe1e --- /dev/null +++ b/product/pc/src/main/ets/pages/Countdown.ets @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CountdownView, CountdownController, CountdownState, TimeSelectView } from '@ohos/countdown' +import { ImageComponent, ConfigData } from '@ohos/common' + +@Component +export struct CountDown { + private headName: ResourceStr = $r("app.string.timer_clock") + @State totalTime: number = 0; + @State currentTime: number = 0; + @State state: CountdownState = CountdownState.IDLE; + private controller: CountdownController = new CountdownController(); + @State hour: string = "00"; + @State minute: string = "00"; + @State second: string = "00"; + + build() { + Row() { + Column() { + Row() { + Text(this.headName) + .fontSize($r("app.float.font_30")) + .fontWeight(500) + .fontColor($r("app.color.text_color")) + .lineHeight($r("app.float.wh_value_21")) + }.width(ConfigData.WH_100_100) + .padding({ left: $r("app.float.wh_value_24") }) + .height($r("app.float.wh_value_28")) + + Column() { + CountdownView({ + viewSize: 232, + totalTime: this.totalTime, + currentTime: this.currentTime, + state: this.state, + originRadius: 5, + scaleWidth: 2, + scaleHeight: 10, + scalePadding: 5 + }) + }.margin({ top: $r("app.float.wh_value_38"), bottom: $r("app.float.wh_value_38") }) + + Column() { + Text(this.hour + ":" + this.minute + ":" + this.second) + .lineHeight($r("app.float.wh_value_16")) + .fontColor($r("app.color.text_color")) + .fontWeight(500) + .fontSize($r("app.float.font_20")) + }.width(ConfigData.WH_100_100) + } + .height(ConfigData.WH_100_100) + .width($r("app.float.wh_value_304")) + + Divider().vertical(true).width($r("app.float.wh_value_0_5")) + Column() { + Column() { + TimeSelectView({ + marginRight: $r("app.float.distance_19"), + dividerMargin: $r("app.float.distance_19"), + hour: $hour, + minute: $minute, + second: $second, + sca: 0.6, + callBack: this.timeSelectCallBack + }) + } + .justifyContent(FlexAlign.Center) + .visibility((this.state == CountdownState.IDLE || this.state == CountdownState.PREPARED) ? Visibility.Visible : Visibility.Hidden) + .padding($r("app.float.distance_12")) + .height($r("app.float.wh_value_324")) + .flexShrink(1) + + Row() { + Row() { + ImageComponent({ + color: $r("app.color.white"), + imageSrc: $r("app.media.ic_clock_refresh"), + imgLength: 12 + }) + } + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) + .onClick(() => { + this.controller.reset() + }) + + Row() { + ImageComponent({ + color: $r("app.color.selected_text_color"), + imageSrc: this.state == CountdownState.RUNNING ? $r('app.media.ic_clock_suspend') : $r('app.media.ic_clock_play'), + imgLength: 12 + }) + } + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) + .onClick(() => { + if (this.state == CountdownState.PREPARED) { + this.controller.setTime(this.totalTime) + this.controller.start() + } else if (this.state == CountdownState.PAUSED) { + this.controller.start() + } else if (this.state == CountdownState.RUNNING) { + this.controller.pause() + } + }) + + Row() { + ImageComponent({ + color: $r("app.color.white"), + imageSrc: $r('app.media.ic_clock_sound'), + imgLength: 12 + }) + } + .onClick(() => { + }) + } + .height($r("app.float.wh_value_24")) + .width(ConfigData.WH_100_100) + .justifyContent(FlexAlign.SpaceBetween) + .margin({ bottom: $r("app.float.distance_10"), top: $r("app.float.distance_4") }) + .padding({ left: $r("app.float.distance_84"), right: $r("app.float.distance_84") }) + } + .height(ConfigData.WH_100_100) + .width($r("app.float.wh_value_275_5")) + } + } + + /** + * CallBack for TimeSelectView. + */ + private timeSelectCallBack: () => void = () => { + this.totalTime = (parseInt(this.hour) * 3600 + parseInt(this.minute) * 60 + parseInt(this.second)) * 1000 + + this.controller.setTime(this.totalTime) + } + + aboutToAppear() { + this.controller.setStateUpdateListener((state) => { + this.state = state + if (state == CountdownState.STOPPED) { + let date = new Date(this.totalTime) + this.hour = this.fill(date.getHours()) + this.minute = this.fill(date.getMinutes()) + this.second = this.fill(date.getSeconds()) + this.controller.reStart() + } + }) + this.controller.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + this.currentTime = currentTimeMs + this.totalTime = totalTimeMs + let date = new Date(this.currentTime) + this.hour = this.fill(date.getHours()) + this.minute = this.fill(date.getMinutes()) + this.second = this.fill(date.getSeconds()) + }) + this.controller.getData(); + } + + /** + * Make up 0 if less than 10. + */ + fill(value) { + return (value > 9 ? "" : "0") + value; + } +} \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/index.ets b/product/pc/src/main/ets/pages/index.ets new file mode 100644 index 0000000..d23cced --- /dev/null +++ b/product/pc/src/main/ets/pages/index.ets @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ConfigData } from '@ohos/common' +import { Timer } from './timer/Timer' +import { CountDown } from './Countdown' + +@Entry +@Component +struct Index { + featureList: Array = [ + { + name: $r("app.string.alarm_clock"), + icon: $r("app.media.ic_clock_clock"), + selectedIcon: $r("app.media.ic_clock_clock_click") + }, + { + name: $r("app.string.stopwatch"), + icon: $r("app.media.ic_clock_timer"), + selectedIcon: $r("app.media.ic_clock_timer_click") + }, + { + name: $r("app.string.timer_clock"), + icon: $r("app.media.ic_clock_second_chronograph"), + selectedIcon: $r("app.media.ic_clock_second_chronograph_click") + }, + ] + @State featureIndex: number = 1 + + build() { + Row() { + Column() { + ForEach(this.featureList.map((value, index) => { + return { i: index, data: value } + }), item => { + Column() { + Image(this.featureIndex == item.i ? item.data.selectedIcon : item.data.icon) + .width($r("app.float.wh_value_12")) + .height($r("app.float.wh_value_12")) + Text(item.data.name) + .fontColor(this.featureIndex == item.i ? $r("app.color.selected_text_color") : $r("app.color.text_color")) + .fontSize($r("app.float.font_10")) + .margin({ top: $r("app.float.distance_1") }) + } + .onClick(() => { + this.featureIndex = item.i + }) + }, item => item.i) + + } + .backgroundColor($r("app.color.background_color_white")) + .padding({ top: $r("app.float.wh_value_118"), bottom: $r("app.float.wh_value_118") }) + .height(ConfigData.WH_100_100) + .justifyContent(FlexAlign.SpaceBetween) + .width($r("app.float.wh_value_60")) + + Row() { + Column() { + Timer() + }.visibility(this.featureIndex == 1 ? Visibility.Visible : Visibility.None) + + Column() { + CountDown() + }.visibility(this.featureIndex == 2 ? Visibility.Visible : Visibility.None) + } + .width(ConfigData.WH_100_100) + .height(ConfigData.WH_100_100) + .flexShrink(1) + }.backgroundColor($r("app.color.background_color")) + .width(ConfigData.WH_100_100) + .height(ConfigData.WH_100_100) + } +} \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets new file mode 100644 index 0000000..9626f99 --- /dev/null +++ b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerController } from "@ohos/timer" +import { TimerUtil, ConfigData } from '@ohos/common' + +@Component +export struct CurrentTimeDisplay { + @State currentTime: number = 0 + @Prop lastTimeMs: number + @State timerController: TimerController = new TimerController() + + aboutToAppear() { + this.timerController.setTimeUpdateListener((currentTimeMs: number) => { + this.currentTime = currentTimeMs + }) + } + + build() { + Column() { + Text(TimerUtil.timeFormat(this.currentTime)) + .lineHeight($r("app.float.wh_value_16")) + .fontColor($r("app.color.text_color")) + .fontWeight(500) + .fontSize($r("app.float.font_20")) + Text(TimerUtil.timeFormat(this.currentTime - this.lastTimeMs)) + .lineHeight($r("app.float.wh_value_12")) + .fontColor($r("app.color.text_color")) + .opacity($r("app.float.opacity_6")) + .fontSize($r("app.float.font_14")) + .visibility(this.lastTimeMs > 0 ? Visibility.Visible : Visibility.Hidden) + }.width(ConfigData.WH_100_100) + } +} \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets new file mode 100644 index 0000000..3afb844 --- /dev/null +++ b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerUtil, ConfigData } from '@ohos/common' + +@Component +export struct TimeOfRecord { + @State timeList: Array = [] + @Prop lastTimeMs: number + + build() { + Column() { + List() { + ForEach(this.timeList.map((value, index) => { + return { i: index, data: this.timeList[this.timeList.length - index-1] } + }), (item) => { + ListItem() { + Row() { + Row() { + Text(TimerUtil.addZero(this.timeList.length - item.i)) + .fontColor($r("app.color.text_color")) + .fontSize($r("app.float.font_14")) + .fontWeight(500) + Text("+" + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) + .width($r("app.float.wh_value_60")) + .textAlign(TextAlign.Center) + .fontSize($r("app.float.font_14")) + .fontColor($r("app.color.text_color")) + .opacity($r("app.float.opacity_6")) + } + .width($r("app.float.wh_value_151")) + .justifyContent(FlexAlign.SpaceBetween) + + Text(TimerUtil.timeFormat(item.data)) + .fontSize($r("app.float.font_14")) + .fontColor($r("app.color.text_color")) + .fontWeight(500) + }.width(ConfigData.WH_100_100) + .height(ConfigData.WH_100_100) + .justifyContent(FlexAlign.SpaceBetween) + .padding({ left: $r("app.float.distance_12"), right: $r("app.float.distance_12") }) + } + .height($r("app.float.wh_value_28")) + .width(ConfigData.WH_100_100) + .clip(true) + }, item => item.i) + } + .backgroundColor($r("app.color.background_color_white")) + + .borderRadius($r("app.float.distance_12")) + .margin({ top: $r("app.float.distance_40") }) + + }.padding($r("app.float.distance_12")) + .height($r("app.float.wh_value_324")) + .flexShrink(1) + } +} \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/timer/Timer.ets b/product/pc/src/main/ets/pages/timer/Timer.ets new file mode 100644 index 0000000..0bea8e1 --- /dev/null +++ b/product/pc/src/main/ets/pages/timer/Timer.ets @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerController } from "@ohos/timer" +import { ConfigData } from '@ohos/common' +import { TimerClock } from './TimerClock' +import { CurrentTimeDisplay } from './CurrentTimeDisplay' +import { TimeOfRecord } from './TimeOfRecord' +import { TimerControl } from './TimerControl' + +@Component +export struct Timer { + timerController: TimerController = new TimerController() + private timeList: Array = [] + @State lastTimeMs: number = 0 + + aboutToAppear() { + this.timerController.setTimeListUpdateListener((timeList: Array, lastTimeMs: number) => { + this.timeList = timeList + this.lastTimeMs = lastTimeMs + }) + setTimeout(() => { + this.timerController.reload() + }, 100) + } + + build() { + Row() { + Column() { + Row() { + Text($r("app.string.stopwatch")) + .fontSize($r("app.float.font_30")) + .fontWeight(500) + .fontColor($r("app.color.text_color")) + .lineHeight($r("app.float.wh_value_21")) + }.width(ConfigData.WH_100_100) + .padding({ left: $r("app.float.wh_value_24") }) + .height($r("app.float.wh_value_28")) + + Column() { + TimerClock({ timerController: this.timerController }) + }.margin({ top: $r("app.float.wh_value_38"), bottom: $r("app.float.wh_value_38") }) + + CurrentTimeDisplay({ timerController: this.timerController, lastTimeMs: this.lastTimeMs }) + } + .height(ConfigData.WH_100_100) + .width($r("app.float.wh_value_304")) + + Divider().vertical(true).width($r("app.float.wh_value_0_5")).opacity($r("app.float.opacity_1")) + Column() { + TimeOfRecord({ timeList: this.timeList, lastTimeMs: this.lastTimeMs }) + TimerControl({ timerController: this.timerController, timeList: this.timeList }) + } + .height(ConfigData.WH_100_100) + .width($r("app.float.wh_value_275_5")) + } + } +} \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/timer/TimerClock.ets b/product/pc/src/main/ets/pages/timer/TimerClock.ets new file mode 100644 index 0000000..47e1a8c --- /dev/null +++ b/product/pc/src/main/ets/pages/timer/TimerClock.ets @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerView, TimerController } from "@ohos/timer" + +const CLOCK_SIZE = 232 + +@Component +export struct TimerClock { + @State currentTime: number = 0 + @State timerController: TimerController = new TimerController() + + aboutToAppear() { + this.timerController.setClockUpdateListener((currentTimeMs: number) => { + this.currentTime = currentTimeMs + }) + } + + build() { + Column() { + TimerView({ sSize: CLOCK_SIZE, currentTime: this.currentTime }) + } + } +} \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/timer/TimerControl.ets b/product/pc/src/main/ets/pages/timer/TimerControl.ets new file mode 100644 index 0000000..8a028e0 --- /dev/null +++ b/product/pc/src/main/ets/pages/timer/TimerControl.ets @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerController, TimerState } from "@ohos/timer" +import { ImageComponent, ConfigData } from '@ohos/common' + +const DEFAULT_ICON_SIZE: number = 12 + +@Component +export struct TimerControl { + private timerController: TimerController = new TimerController() + @State state: TimerState = TimerState.IDLE + private timeList: Array = [] + + aboutToAppear() { + this.timerController.setStateUpdateListener((state) => { + this.state = state + }) + } + + build() { + Row() { + Row() { + ImageComponent({ + color: $r("app.color.white"), + imageSrc: $r("app.media.ic_clock_refresh"), + imgLength: DEFAULT_ICON_SIZE + }) + } + .opacity(this.state == TimerState.PAUSED ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .enabled(this.state == TimerState.PAUSED) + .onClick(() => { + this.timerController.reset() + }) + + Row() { + ImageComponent({ + color: $r("app.color.selected_text_color"), + imageSrc: this.state == TimerState.RUNNING ? + $r("app.media.ic_clock_suspend") : + $r("app.media.ic_clock_play"), imgLength: DEFAULT_ICON_SIZE + }) + }.onClick(() => { + if (this.state == TimerState.IDLE) { + this.timerController.start() + } else if (this.state == TimerState.RUNNING) { + this.timerController.pause() + } else if (this.state == TimerState.PAUSED) { + this.timerController.start() + } + }) + + Row() { + ImageComponent({ + color: $r("app.color.white"), + imageSrc: $r("app.media.ic_clock_timer2"), + imgLength: DEFAULT_ICON_SIZE + }) + } + .opacity(this.state == TimerState.RUNNING ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .enabled(this.state == TimerState.RUNNING) + .onClick(() => { + this.timerController.writeTime() + }) + } + .height($r("app.float.wh_value_24")) + .width(ConfigData.WH_100_100) + .justifyContent(FlexAlign.SpaceBetween) + .margin({ bottom: $r("app.float.distance_10"), top: $r("app.float.distance_4") }) + .padding({ left: $r("app.float.distance_84"), right: $r("app.float.distance_84") }) + .shadow({ radius: $r("app.float.wh_value_28"), offsetY: -60, color: $r("app.color.background_color") }) + } +} \ No newline at end of file diff --git a/product/pc/src/main/module.json5 b/product/pc/src/main/module.json5 new file mode 100644 index 0000000..0f92245 --- /dev/null +++ b/product/pc/src/main/module.json5 @@ -0,0 +1,43 @@ +{ + "module": { + "name": "pc", + "type": "entry", + "srcEntrance": "./ets/Application/MyAbilityStage.ts", + "description": "$string:entry_desc", + "mainElement": "MainAbility", + "deviceTypes": [ + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "uiSyntax": "ets", + "abilities": [ + { + "name": "MainAbility", + "srcEntrance": "./ets/MainAbility/MainAbility.ts", + "description": "$string:MainAbility_desc", + "icon": "$media:icon", + "label": "$string:MainAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + { + "name": "ohos.permission.PUBLISH_AGENT_REMINDER" + } + ] + } +} \ No newline at end of file diff --git a/product/pc/src/main/resources/base/element/color.json b/product/pc/src/main/resources/base/element/color.json new file mode 100644 index 0000000..ab58100 --- /dev/null +++ b/product/pc/src/main/resources/base/element/color.json @@ -0,0 +1,12 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + }, + { + "name": "background_color", + "value": "#F1F3F5" + } + ] +} \ No newline at end of file diff --git a/product/pc/src/main/resources/base/element/float.json b/product/pc/src/main/resources/base/element/float.json new file mode 100644 index 0000000..110b59a --- /dev/null +++ b/product/pc/src/main/resources/base/element/float.json @@ -0,0 +1,120 @@ +{ + "float": [ + { + "name": "wh_value_0_5", + "value": "0.5vp" + }, + { + "name": "wh_value_12", + "value": "12vp" + }, + { + "name": "wh_value_16", + "value": "16vp" + }, + { + "name": "wh_value_21", + "value": "21vp" + }, + { + "name": "wh_value_24", + "value": "24vp" + }, + { + "name": "wh_value_28", + "value": "28vp" + }, + { + "name": "wh_value_38", + "value": "38vp" + }, + { + "name": "wh_value_60", + "value": "60vp" + }, + { + "name": "wh_value_118", + "value": "118vp" + }, + { + "name": "wh_value_151", + "value": "151vp" + }, + { + "name": "wh_value_275_5", + "value": "275.5vp" + }, + { + "name": "wh_value_304", + "value": "304vp" + }, + { + "name": "wh_value_324", + "value": "324vp" + }, + { + "name": "font_10", + "value": "10px" + }, + { + "name": "font_14", + "value": "14px" + }, + { + "name": "font_16", + "value": "16px" + }, + { + "name": "font_20", + "value": "20px" + }, + { + "name": "font_30", + "value": "30px" + }, + { + "name": "distance_1", + "value": "1vp" + }, + { + "name": "distance_4", + "value": "4vp" + }, + { + "name": "distance_10", + "value": "10vp" + }, + { + "name": "distance_12", + "value": "12vp" + }, + { + "name": "distance_19", + "value": "19vp" + }, + { + "name": "distance_40", + "value": "40vp" + }, + { + "name": "distance_84", + "value": "84vp" + }, + { + "name": "opacity_1", + "value": "0.1" + }, + { + "name": "opacity_4", + "value": "0.4" + }, + { + "name": "opacity_6", + "value": "0.6" + }, + { + "name": "opacity_full", + "value": "1" + } + ] +} \ No newline at end of file diff --git a/product/pc/src/main/resources/base/element/string.json b/product/pc/src/main/resources/base/element/string.json new file mode 100644 index 0000000..b2dcdc7 --- /dev/null +++ b/product/pc/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_desc", + "value": "description" + }, + { + "name": "MainAbility_desc", + "value": "description" + }, + { + "name": "MainAbility_label", + "value": "时钟" + } + ] +} \ No newline at end of file diff --git a/product/pc/src/main/resources/base/media/icon.png b/product/pc/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5af1e0d50a73f3cbd710198786dce64c7bf02d95 GIT binary patch literal 4155 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 FV1k!j!Z82< literal 0 HcmV?d00001 diff --git a/product/pc/src/main/resources/base/profile/main_pages.json b/product/pc/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000..feec276 --- /dev/null +++ b/product/pc/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/index" + ] +} diff --git a/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts b/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts new file mode 100644 index 0000000..2e8d465 --- /dev/null +++ b/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -0,0 +1,7 @@ +import AbilityStage from "@ohos.application.AbilityStage" + +export default class TestAbilityStage extends AbilityStage { + onCreate() { + console.log("[Demo] TestAbilityStage onCreate") + } +} \ No newline at end of file diff --git a/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts b/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts new file mode 100644 index 0000000..301aaf6 --- /dev/null +++ b/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts @@ -0,0 +1,45 @@ +import Ability from '@ohos.application.Ability' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' +import { Hypium } from '@ohos/hypium' +import testsuite from '../test/List.test' + +export default class TestAbility extends Ability { + onCreate(want, launchParam) { + console.log('TestAbility onCreate') + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + console.info('start run testcase!!!') + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + console.log('TestAbility onDestroy') + } + + onWindowStageCreate(windowStage) { + console.log('TestAbility onWindowStageCreate') + windowStage.loadContent("TestAbility/pages/index", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) + }); + + globalThis.abilityContext = this.context; + } + + onWindowStageDestroy() { + console.log('TestAbility onWindowStageDestroy') + } + + onForeground() { + console.log('TestAbility onForeground') + } + + onBackground() { + console.log('TestAbility onBackground') + } +}; \ No newline at end of file diff --git a/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets b/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets new file mode 100644 index 0000000..733600a --- /dev/null +++ b/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets @@ -0,0 +1,34 @@ +import router from '@ohos.router'; + +@Entry +@Component +struct Index { + aboutToAppear() { + console.info('TestAbility index aboutToAppear') + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts b/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000..bdbe7cf --- /dev/null +++ b/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +import TestRunner from '@ohos.application.testRunner' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +function translateParamsToString(parameters) { + const keySet = new Set([ + '-s class', '-s notClass', '-s suite', '-s it', + '-s level', '-s testType', '-s size', '-s timeout', + '-s dryRun' + ]) + let targetParams = ''; + for (const key in parameters) { + if (keySet.has(key)) { + targetParams = `${targetParams} ${key} ${parameters[key]}` + } + } + return targetParams.trim() +} + +async function onAbilityCreateCallback() { + console.log("onAbilityCreateCallback"); +} + +async function addAbilityMonitorCallback(err: any) { + console.info("addAbilityMonitorCallback : " + JSON.stringify(err)) +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + console.info("OpenHarmonyTestRunner OnPrepare ") + } + + async onRun() { + console.log('OpenHarmonyTestRunner onRun run') + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + cmd += ' '+translateParamsToString(abilityDelegatorArguments.parameters) + var debug = abilityDelegatorArguments.parameters["-D"] + if (debug == 'true') + { + cmd += ' -D' + } + console.info('cmd : '+cmd) + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + console.info('executeShellCommand : err : ' + JSON.stringify(err)); + console.info('executeShellCommand : data : ' + d.stdResult); + console.info('executeShellCommand : data : ' + d.exitCode); + }) + console.info('OpenHarmonyTestRunner onRun end') + } +}; \ No newline at end of file diff --git a/product/pc/src/ohosTest/ets/test/Ability.test.ets b/product/pc/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000..df49ed0 --- /dev/null +++ b/product/pc/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,13 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + it('assertContain',0, function () { + console.info("it begin") + let a = 'abc' + let b = 'b' + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/product/pc/src/ohosTest/ets/test/List.test.ets b/product/pc/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000..d766fe2 --- /dev/null +++ b/product/pc/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/product/pc/src/ohosTest/module.json5 b/product/pc/src/ohosTest/module.json5 new file mode 100644 index 0000000..0f40197 --- /dev/null +++ b/product/pc/src/ohosTest/module.json5 @@ -0,0 +1,39 @@ +{ + "module": { + "name": "pc_test", + "type": "feature", + "srcEntrance": "./ets/Application/TestAbilityStage.ts", + "description": "$string:entry_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "uiSyntax": "ets", + "abilities": [ + { + "name": "TestAbility", + "srcEntrance": "./ets/TestAbility/TestAbility.ts", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "visible": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/product/pc/src/ohosTest/resources/base/element/color.json b/product/pc/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000..1bbc9aa --- /dev/null +++ b/product/pc/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/product/pc/src/ohosTest/resources/base/element/string.json b/product/pc/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000..36d4230 --- /dev/null +++ b/product/pc/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/product/pc/src/ohosTest/resources/base/media/icon.png b/product/pc/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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 { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + console.log("[Demo] MainAbility onWindowStageDestroy") + } + + onForeground() { + // Ability has brought to foreground + console.log("[Demo] MainAbility onForeground") + } + + onBackground() { + // Ability has back to background + console.log("[Demo] MainAbility onBackground") + } +}; diff --git a/product/phone/src/main/ets/pages/Countdown.ets b/product/phone/src/main/ets/pages/Countdown.ets new file mode 100644 index 0000000..efa0338 --- /dev/null +++ b/product/phone/src/main/ets/pages/Countdown.ets @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CountdownView, CountdownController, CountdownState, TimeSelectView } from '@ohos/countdown' +import { ImageComponent, ConfigData } from '@ohos/common' + +@Component +export struct CountDown { + private headName: ResourceStr = $r("app.string.timer_clock") + @State totalTime: number = 0; + @State currentTime: number = 0; + @State state: CountdownState = CountdownState.IDLE; + private controller: CountdownController = new CountdownController(); + @State hour: string = "00"; + @State minute: string = "00"; + @State second: string = "00"; + + build() { + Column() { + Row() { + Text(this.headName) + .fontSize($r("app.float.font_48")) + .fontColor($r("app.color.text_color")) + .lineHeight($r("app.float.wh_value_44")) + .fontWeight(500) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .textAlign(TextAlign.Center) + .margin({ top: $r("app.float.distance_18_5"), bottom: $r("app.float.distance_12") }) + } + .width(ConfigData.WH_100_100) + + Scroll() { + Column() { + Column() { + CountdownView({ + viewSize: 373.5, + totalTime: this.totalTime, + currentTime: this.currentTime, + state: this.state + }) + } + .margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_16") }) + + Text(this.hour + ":" + this.minute + ":" + this.second) + .fontSize($r("app.float.font_40")) + .fontColor($r("app.color.text_color")) + .lineHeight($r("app.float.wh_value_32")) + .fontWeight(500) + + Column() { + TimeSelectView({ + hour: $hour, + minute: $minute, + second: $second, + callBack: this.timeSelectCallBack + }) + } + .margin({ top: $r("app.float.distance_42"), bottom: $r("app.float.distance_24") }) + .visibility((this.state == CountdownState.IDLE || this.state == CountdownState.PREPARED) ? Visibility.Visible : Visibility.None) + } + } + .height($r("app.float.wh_value_516")) + .width(ConfigData.WH_100_100) + .scrollBar(BarState.Off) + + Row() { + Row() { + ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_refresh') }) + } + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) + .onClick(() => { + this.controller.reset() + }) + + Row() { + ImageComponent({ + color: $r("app.color.selected_text_color"), + imageSrc: this.state == CountdownState.RUNNING ? $r('app.media.ic_clock_suspend') : $r('app.media.ic_clock_play') + }) + } + .margin({ left: $r("app.float.distance_48"), right: $r("app.float.distance_48") }) + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) + .onClick(() => { + if (this.state == CountdownState.PREPARED) { + this.controller.setTime(this.totalTime) + this.controller.start() + } else if (this.state == CountdownState.PAUSED) { + this.controller.start() + } else if (this.state == CountdownState.RUNNING) { + this.controller.pause() + } + }) + + Row() { + ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_sound') }) + } + .onClick(() => { + }) + }.margin({ top: $r("app.float.distance_16"), bottom: $r("app.float.distance_16") }) + } + .width(ConfigData.WH_100_100) + .height(ConfigData.WH_100_100) + .padding({ left: $r("app.float.distance_32"), right: $r("app.float.distance_32") }) + } + + /** + * CallBack for TimeSelectView. + */ + private timeSelectCallBack: () => void = () => { + this.totalTime = (parseInt(this.hour) * 3600 + parseInt(this.minute) * 60 + parseInt(this.second)) * 1000 + + this.controller.setTime(this.totalTime) + } + + aboutToAppear() { + this.controller.setStateUpdateListener((state) => { + this.state = state + if (state == CountdownState.STOPPED) { + let date = new Date(this.totalTime) + this.hour = this.fill(date.getHours()) + this.minute = this.fill(date.getMinutes()) + this.second = this.fill(date.getSeconds()) + this.controller.reStart() + } + }) + this.controller.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + this.currentTime = currentTimeMs + this.totalTime = totalTimeMs + let date = new Date(this.currentTime) + this.hour = this.fill(date.getHours()) + this.minute = this.fill(date.getMinutes()) + this.second = this.fill(date.getSeconds()) + }) + this.controller.getData(); + } + + /** + * Make up 0 if less than 10. + */ + fill(value) { + return (value > 9 ? "" : "0") + value; + } +} \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/index.ets b/product/phone/src/main/ets/pages/index.ets new file mode 100644 index 0000000..ce4de7b --- /dev/null +++ b/product/phone/src/main/ets/pages/index.ets @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ConfigData } from '@ohos/common' +import { Timer } from './timer/Timer' +import { CountDown } from './Countdown' + +@Entry +@Component +struct Index { + featureList: Array = [ + { + name: $r("app.string.alarm_clock"), + icon: $r("app.media.ic_clock_clock"), + selectedIcon: $r("app.media.ic_clock_clock_click") + }, + { + name: $r("app.string.stopwatch"), + icon: $r("app.media.ic_clock_timer"), + selectedIcon: $r("app.media.ic_clock_timer_click") + }, + { + name: $r("app.string.timer_clock"), + icon: $r("app.media.ic_clock_second_chronograph"), + selectedIcon: $r("app.media.ic_clock_second_chronograph_click") + }, + ] + @State featureIndex: number = 1 + + build() { + Column() { + Column() { + Column() { + Timer() + }.visibility(this.featureIndex == 1 ? Visibility.Visible : Visibility.None) + + Column() { + CountDown() + }.visibility(this.featureIndex == 2 ? Visibility.Visible : Visibility.None) + } + .width(ConfigData.WH_100_100) + .height(ConfigData.WH_100_100) + .flexShrink(1) + + Row() { + ForEach(this.featureList.map((value, index) => { + return { i: index, data: value } + }), item => { + Column() { + Image(this.featureIndex == item.i ? item.data.selectedIcon : item.data.icon) + .width($r("app.float.wh_value_32")) + .height($r("app.float.wh_value_32")) + Text(item.data.name) + .fontColor(this.featureIndex == item.i ? $r("app.color.selected_text_color") : $r("app.color.text_color")) + .fontSize($r("app.float.font_24")) + .margin({ top: $r("app.float.distance_3") }) + }.width(ConfigData.WH_33_100) + .onClick(() => { + this.featureIndex = item.i + }) + }, item => item.i) + } + .height($r("app.float.wh_value_75")) + .width(ConfigData.WH_100_100) + .justifyContent(FlexAlign.Center) + } + .width(ConfigData.WH_100_100) + .height(ConfigData.WH_100_100) + .backgroundColor($r("app.color.background_color")) + } +} \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets new file mode 100644 index 0000000..ca62137 --- /dev/null +++ b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerController } from "@ohos/timer" +import { TimerUtil, ConfigData } from '@ohos/common' + +@Component +export struct CurrentTimeDisplay { + @State currentTime: number = 0 + @Prop lastTimeMs: number + @State timerController: TimerController = new TimerController() + + aboutToAppear() { + this.timerController.setTimeUpdateListener((currentTimeMs: number) => { + this.currentTime = currentTimeMs + }) + } + + build() { + Column() { + Text(TimerUtil.timeFormat(this.currentTime)) + .lineHeight($r("app.float.wh_value_32")) + .fontColor($r("app.color.text_color")) + .fontWeight(500) + .fontSize($r("app.float.font_40")) + Text(TimerUtil.timeFormat(this.currentTime - this.lastTimeMs)) + .lineHeight($r("app.float.wh_value_32")) + .fontColor($r("app.color.text_color")) + .opacity($r("app.float.opacity_6")) + .fontSize($r("app.float.font_28")) + .visibility(this.lastTimeMs > 0 ? Visibility.Visible : Visibility.Hidden) + }.width(ConfigData.WH_100_100) + } +} \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets new file mode 100644 index 0000000..1652930 --- /dev/null +++ b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerUtil, ConfigData } from '@ohos/common' + +@Component +export struct TimeOfRecord { + @State timeList: Array = [] + @Prop lastTimeMs: number + + build() { + Column() { + List() { + ForEach(this.timeList.map((value, index) => { + return { i: index, data: this.timeList[this.timeList.length - index-1] } + }), (item) => { + ListItem() { + Row() { + Row() { + Text(TimerUtil.addZero(this.timeList.length - item.i)) + .fontSize($r("app.float.font_28")) + .fontColor($r("app.color.text_color")) + .fontWeight(500) + Text("+" + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) + .width($r("app.float.wh_value_150")) + .textAlign(TextAlign.Center) + .fontSize($r("app.float.font_28")) + .fontColor($r("app.color.text_color")) + .opacity($r("app.float.opacity_6")) + } + .width($r("app.float.wh_value_280")) + .justifyContent(FlexAlign.SpaceBetween) + + Text(TimerUtil.timeFormat(item.data)) + .fontSize($r("app.float.font_28")) + .fontColor($r("app.color.text_color")) + .fontWeight(500) + }.width(ConfigData.WH_100_100) + .height(ConfigData.WH_100_100) + .justifyContent(FlexAlign.SpaceBetween) + .padding({ left: $r("app.float.distance_16"), right: $r("app.float.distance_16") }) + } + .height($r("app.float.wh_value_75")) + .width(ConfigData.WH_100_100) + .clip(true) + }, item => item.i) + } + .backgroundColor($r("app.color.background_color_white")) + .borderRadius($r("app.float.distance_32")) + .padding({ top: $r("app.float.distance_6"), bottom: $r("app.float.distance_6") }) + } + .padding({ + left: $r("app.float.distance_16"), + right: $r("app.float.distance_16"), + top: $r("app.float.distance_8"), + bottom: $r("app.float.distance_8") + }) + .visibility(this.timeList.length > 0 ? Visibility.Visible : Visibility.None) + } +} \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/timer/Timer.ets b/product/phone/src/main/ets/pages/timer/Timer.ets new file mode 100644 index 0000000..fade5ec --- /dev/null +++ b/product/phone/src/main/ets/pages/timer/Timer.ets @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerController } from "@ohos/timer" +import { ConfigData } from '@ohos/common' +import { TimerClock } from './TimerClock' +import { CurrentTimeDisplay } from './CurrentTimeDisplay' +import { TimeOfRecord } from './TimeOfRecord' +import { TimerControl } from './TimerControl' + +@Component +export struct Timer { + private timerController: TimerController = new TimerController() + private timeList: Array = [] + @State lastTimeMs: number = 0 + + aboutToAppear() { + this.timerController.setTimeListUpdateListener((timeList: Array, lastTimeMs: number) => { + this.timeList = timeList + this.lastTimeMs = lastTimeMs + }) + setTimeout(() => { + this.timerController.reload() + }, 100) + } + + build() { + Column() { + Row() { + Text($r("app.string.stopwatch")) + .fontSize($r("app.float.font_48")) + .fontColor($r("app.color.text_color")) + .lineHeight($r("app.float.wh_value_44")) + .fontWeight(500) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .textAlign(TextAlign.Center) + .margin({ top: $r("app.float.distance_18_5"), bottom: $r("app.float.distance_12") }) + } + .padding({ left: $r("app.float.wh_value_32") }) + .width(ConfigData.WH_100_100) + + List() { + ListItem() { + TimerClock({ timerController: this.timerController }) + }.margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_16") }) + + ListItem() { + CurrentTimeDisplay({ timerController: this.timerController, lastTimeMs: this.lastTimeMs }) + } + .sticky(Sticky.Normal) + .backgroundColor($r("app.color.background_color")) + .shadow({ radius: $r("app.float.wh_value_20"), offsetY: 30, color: $r("app.color.background_color") }) + .margin({ bottom: $r("app.float.distance_8") }) + + ListItem() { + TimeOfRecord({ timeList: this.timeList, lastTimeMs: this.lastTimeMs }) + } + } + .width(ConfigData.WH_100_100) + .height($r("app.float.wh_value_526")) + .scrollBar(BarState.Off) + .edgeEffect(EdgeEffect.None) + + TimerControl({ timerController: this.timerController, timeList: this.timeList }) + } + } +} \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/timer/TimerClock.ets b/product/phone/src/main/ets/pages/timer/TimerClock.ets new file mode 100644 index 0000000..c39f485 --- /dev/null +++ b/product/phone/src/main/ets/pages/timer/TimerClock.ets @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerView, TimerController } from "@ohos/timer" + +const CLOCK_SIZE = 373.5 + +@Component +export struct TimerClock { + @State currentTime: number = 0 + @State timerController: TimerController = new TimerController() + + aboutToAppear() { + this.timerController.setClockUpdateListener((currentTimeMs: number) => { + this.currentTime = currentTimeMs + }) + } + + build() { + Column() { + TimerView({ sSize: CLOCK_SIZE, currentTime: this.currentTime }) + } + } +} \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/timer/TimerControl.ets b/product/phone/src/main/ets/pages/timer/TimerControl.ets new file mode 100644 index 0000000..8c8558f --- /dev/null +++ b/product/phone/src/main/ets/pages/timer/TimerControl.ets @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TimerController, TimerState } from "@ohos/timer" +import { ImageComponent, ConfigData } from '@ohos/common' + +@Component +export struct TimerControl { + private timerController: TimerController = new TimerController() + @State state: TimerState = TimerState.IDLE + private timeList: Array = [] + + aboutToAppear() { + this.timerController.setStateUpdateListener((state) => { + this.state = state + }) + } + + build() { + Row() { + Row() { + ImageComponent({ color: $r("app.color.white"), imageSrc: $r("app.media.ic_clock_refresh") }) + } + .opacity(this.state == TimerState.PAUSED ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .enabled(this.state == TimerState.PAUSED) + .onClick(() => { + this.timerController.reset() + }) + + Row() { + ImageComponent({ + color: $r("app.color.selected_text_color"), + imageSrc: this.state == TimerState.RUNNING ? + $r("app.media.ic_clock_suspend") : + $r("app.media.ic_clock_play") + }) + }.onClick(() => { + if (this.state == TimerState.IDLE) { + this.timerController.start() + } else if (this.state == TimerState.RUNNING) { + this.timerController.pause() + } else if (this.state == TimerState.PAUSED) { + this.timerController.start() + } + }) + + Row() { + ImageComponent({ color: $r("app.color.white"), imageSrc: $r("app.media.ic_clock_timer2") }) + } + .opacity(this.state == TimerState.RUNNING ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .enabled(this.state == TimerState.RUNNING) + .onClick(() => { + this.timerController.writeTime() + }) + } + .height($r("app.float.wh_value_64")) + .width(ConfigData.WH_100_100) + .justifyContent(FlexAlign.SpaceBetween) + .margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_6") }) + .padding({ left: $r("app.float.distance_96"), right: $r("app.float.distance_96") }) + .shadow({ radius: $r("app.float.wh_value_20"), offsetY: -40, color: $r("app.color.background_color") }) + } +} \ No newline at end of file diff --git a/product/phone/src/main/module.json5 b/product/phone/src/main/module.json5 new file mode 100644 index 0000000..c928eb4 --- /dev/null +++ b/product/phone/src/main/module.json5 @@ -0,0 +1,38 @@ +{ + "module": { + "name": "phone", + "type": "entry", + "srcEntrance": "./ets/Application/MyAbilityStage.ts", + "description": "$string:phone_desc", + "mainElement": "MainAbility", + "deviceTypes": [ + "default" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "uiSyntax": "ets", + "abilities": [ + { + "name": "MainAbility", + "srcEntrance": "./ets/MainAbility/MainAbility.ts", + "description": "$string:MainAbility_desc", + "icon": "$media:icon", + "label": "$string:MainAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/product/phone/src/main/resources/base/element/float.json b/product/phone/src/main/resources/base/element/float.json new file mode 100644 index 0000000..4975c10 --- /dev/null +++ b/product/phone/src/main/resources/base/element/float.json @@ -0,0 +1,129 @@ +{ + "float": [ + { + "name": "wh_value_20", + "value": "20vp" + }, + { + "name": "wh_value_32", + "value": "32vp" + }, + { + "name": "wh_value_44", + "value": "44vp" + }, + { + "name": "wh_value_64", + "value": "64vp" + }, + { + "name": "wh_value_75", + "value": "75vp" + }, + { + "name": "wh_value_96", + "value": "96vp" + }, + { + "name": "wh_value_150", + "value": "150vp" + }, + { + "name": "wh_value_280", + "value": "280vp" + }, + { + "name": "wh_value_516", + "value": "516vp" + }, + { + "name": "wh_value_526", + "value": "526vp" + }, + { + "name": "font_24", + "value": "24px" + }, + { + "name": "font_28", + "value": "28px" + }, + { + "name": "font_40", + "value": "40px" + }, + { + "name": "font_48", + "value": "48px" + }, + { + "name": "distance_3", + "value": "3vp" + }, + { + "name": "distance_6", + "value": "6vp" + }, + { + "name": "distance_8", + "value": "8vp" + }, + { + "name": "distance_12", + "value": "12vp" + }, + { + "name": "distance_16", + "value": "16vp" + }, + { + "name": "distance_18_5", + "value": "18.5vp" + }, + + { + "name": "distance_24", + "value": "24vp" + }, + { + "name": "distance_26_5", + "value": "26.5vp" + }, + { + "name": "distance_32", + "value": "32vp" + }, + { + "name": "distance_37_5", + "value": "37.5vp" + }, + { + "name": "distance_42", + "value": "42vp" + }, + { + "name": "distance_48", + "value": "48vp" + }, + { + "name": "distance_64", + "value": "64vp" + }, + { + "name": "distance_96", + "value": "96vp" + }, + { + "name": "opacity_4", + "value": "0.4" + }, + { + "name": "opacity_6", + "value": "0.6" + }, + { + "name": "opacity_full", + "value": "1" + } + ] +} \ No newline at end of file diff --git a/product/phone/src/main/resources/base/element/string.json b/product/phone/src/main/resources/base/element/string.json new file mode 100644 index 0000000..9fb9000 --- /dev/null +++ b/product/phone/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "phone_desc", + "value": "description" + }, + { + "name": "MainAbility_desc", + "value": "description" + }, + { + "name": "MainAbility_label", + "value": "时钟" + } + ] +} \ No newline at end of file diff --git a/product/phone/src/main/resources/base/media/icon.png b/product/phone/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5af1e0d50a73f3cbd710198786dce64c7bf02d95 GIT binary patch literal 4155 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 FV1k!j!Z82< literal 0 HcmV?d00001 diff --git a/product/phone/src/main/resources/base/profile/main_pages.json b/product/phone/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000..feec276 --- /dev/null +++ b/product/phone/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/index" + ] +} diff --git a/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts b/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts new file mode 100644 index 0000000..2e8d465 --- /dev/null +++ b/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -0,0 +1,7 @@ +import AbilityStage from "@ohos.application.AbilityStage" + +export default class TestAbilityStage extends AbilityStage { + onCreate() { + console.log("[Demo] TestAbilityStage onCreate") + } +} \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts b/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts new file mode 100644 index 0000000..301aaf6 --- /dev/null +++ b/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts @@ -0,0 +1,45 @@ +import Ability from '@ohos.application.Ability' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' +import { Hypium } from '@ohos/hypium' +import testsuite from '../test/List.test' + +export default class TestAbility extends Ability { + onCreate(want, launchParam) { + console.log('TestAbility onCreate') + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + console.info('start run testcase!!!') + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + console.log('TestAbility onDestroy') + } + + onWindowStageCreate(windowStage) { + console.log('TestAbility onWindowStageCreate') + windowStage.loadContent("TestAbility/pages/index", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) + }); + + globalThis.abilityContext = this.context; + } + + onWindowStageDestroy() { + console.log('TestAbility onWindowStageDestroy') + } + + onForeground() { + console.log('TestAbility onForeground') + } + + onBackground() { + console.log('TestAbility onBackground') + } +}; \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets b/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets new file mode 100644 index 0000000..733600a --- /dev/null +++ b/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets @@ -0,0 +1,34 @@ +import router from '@ohos.router'; + +@Entry +@Component +struct Index { + aboutToAppear() { + console.info('TestAbility index aboutToAppear') + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts b/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000..bdbe7cf --- /dev/null +++ b/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +import TestRunner from '@ohos.application.testRunner' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +function translateParamsToString(parameters) { + const keySet = new Set([ + '-s class', '-s notClass', '-s suite', '-s it', + '-s level', '-s testType', '-s size', '-s timeout', + '-s dryRun' + ]) + let targetParams = ''; + for (const key in parameters) { + if (keySet.has(key)) { + targetParams = `${targetParams} ${key} ${parameters[key]}` + } + } + return targetParams.trim() +} + +async function onAbilityCreateCallback() { + console.log("onAbilityCreateCallback"); +} + +async function addAbilityMonitorCallback(err: any) { + console.info("addAbilityMonitorCallback : " + JSON.stringify(err)) +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + console.info("OpenHarmonyTestRunner OnPrepare ") + } + + async onRun() { + console.log('OpenHarmonyTestRunner onRun run') + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + cmd += ' '+translateParamsToString(abilityDelegatorArguments.parameters) + var debug = abilityDelegatorArguments.parameters["-D"] + if (debug == 'true') + { + cmd += ' -D' + } + console.info('cmd : '+cmd) + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + console.info('executeShellCommand : err : ' + JSON.stringify(err)); + console.info('executeShellCommand : data : ' + d.stdResult); + console.info('executeShellCommand : data : ' + d.exitCode); + }) + console.info('OpenHarmonyTestRunner onRun end') + } +}; \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/test/Ability.test.ets b/product/phone/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000..df49ed0 --- /dev/null +++ b/product/phone/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,13 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + it('assertContain',0, function () { + console.info("it begin") + let a = 'abc' + let b = 'b' + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/test/List.test.ets b/product/phone/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000..d766fe2 --- /dev/null +++ b/product/phone/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/product/phone/src/ohosTest/module.json5 b/product/phone/src/ohosTest/module.json5 new file mode 100644 index 0000000..809f375 --- /dev/null +++ b/product/phone/src/ohosTest/module.json5 @@ -0,0 +1,38 @@ +{ + "module": { + "name": "phone_test", + "type": "feature", + "srcEntrance": "./ets/Application/TestAbilityStage.ts", + "description": "$string:entry_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "uiSyntax": "ets", + "abilities": [ + { + "name": "TestAbility", + "srcEntrance": "./ets/TestAbility/TestAbility.ts", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "visible": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/product/phone/src/ohosTest/resources/base/element/color.json b/product/phone/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000..1bbc9aa --- /dev/null +++ b/product/phone/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/product/phone/src/ohosTest/resources/base/element/string.json b/product/phone/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000..36d4230 --- /dev/null +++ b/product/phone/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/product/phone/src/ohosTest/resources/base/media/icon.png b/product/phone/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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 Date: Thu, 10 Nov 2022 10:28:43 +0800 Subject: [PATCH 02/19] modify codestyle issues Signed-off-by: ding_chengjie --- README.md | 4 +- common/index.ets | 11 +- .../main/ets/components/imageComponent.ets | 15 +- common/src/main/ets/utils/ConfigData.ets | 4 +- common/src/main/ets/utils/LogUtil.ts | 7 +- common/src/main/ets/utils/TimerUtil.ets | 39 +++-- feature/countdown/index.ets | 9 +- .../src/main/ets/components/CountdownView.ets | 117 ++++++------- .../main/ets/components/TimeSelectView.ets | 84 +++++----- .../ets/controller/CountdownController.ets | 156 +++++++++--------- feature/timer/index.ets | 7 +- .../src/main/ets/components/TimerView.ets | 156 +++++++++--------- .../main/ets/controller/TimerController.ets | 154 ++++++++--------- .../main/ets/Application/MyAbilityStage.ts | 3 +- .../src/main/ets/MainAbility/MainAbility.ts | 3 +- product/pc/src/main/ets/pages/Countdown.ets | 123 +++++++------- product/pc/src/main/ets/pages/index.ets | 3 +- .../ets/pages/timer/CurrentTimeDisplay.ets | 3 +- .../src/main/ets/pages/timer/TimeOfRecord.ets | 3 +- product/pc/src/main/ets/pages/timer/Timer.ets | 3 +- .../src/main/ets/pages/timer/TimerClock.ets | 3 +- .../src/main/ets/pages/timer/TimerControl.ets | 3 +- .../main/ets/Application/MyAbilityStage.ts | 3 +- .../src/main/ets/MainAbility/MainAbility.ts | 3 +- .../phone/src/main/ets/pages/Countdown.ets | 93 +++++------ product/phone/src/main/ets/pages/index.ets | 3 +- .../ets/pages/timer/CurrentTimeDisplay.ets | 3 +- .../src/main/ets/pages/timer/TimeOfRecord.ets | 3 +- .../phone/src/main/ets/pages/timer/Timer.ets | 3 +- .../src/main/ets/pages/timer/TimerClock.ets | 3 +- .../src/main/ets/pages/timer/TimerControl.ets | 3 +- 31 files changed, 537 insertions(+), 490 deletions(-) diff --git a/README.md b/README.md index 3b12565..dd910ba 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 录音机应用 +# 时钟应用 - [时钟应用](#时钟应用) - [简介](#简介) @@ -22,7 +22,7 @@ ## 目录 ### 目录结构 ``` -/compass/ +/clock/ ├── common # 公共能力层目录 ├── feature # 公共特性层目录 │ ├── countdown # 倒计时功能目录 diff --git a/common/index.ets b/common/index.ets index 2587a53..0f23c87 100644 --- a/common/index.ets +++ b/common/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { ImageComponent } from './src/main/ets/components/imageComponent' -export { default as ConfigData } from './src/main/ets/utils/ConfigData' +export { ImageComponent } from './src/main/ets/components/imageComponent'; -export { default as TimerUtil } from './src/main/ets/utils/TimerUtil' +export { default as ConfigData } from './src/main/ets/utils/ConfigData'; -export { default as LogUtil } from './src/main/ets/utils/LogUtil' +export { default as TimerUtil } from './src/main/ets/utils/TimerUtil'; + +export { default as LogUtil } from './src/main/ets/utils/LogUtil'; diff --git a/common/src/main/ets/components/imageComponent.ets b/common/src/main/ets/components/imageComponent.ets index 23e2f81..ee1fbf6 100644 --- a/common/src/main/ets/components/imageComponent.ets +++ b/common/src/main/ets/components/imageComponent.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,16 +16,19 @@ @Component export struct ImageComponent { private color: ResourceStr = ''; + private imgLength: number = 32; + private times: number = 2; @State imageSrc: ResourceStr = ''; - private imgLength: number = 32 build() { Stack() { Circle() - .width(this.imgLength * 2) - .height(this.imgLength * 2) - .fill(this.color) - Image(this.imageSrc).height(this.imgLength).width(this.imgLength) + .width(this.imgLength * this.times) + .height(this.imgLength * this.times) + .fill(this.color); + Image(this.imageSrc) + .height(this.imgLength) + .width(this.imgLength); } } } \ No newline at end of file diff --git a/common/src/main/ets/utils/ConfigData.ets b/common/src/main/ets/utils/ConfigData.ets index f4f3b5e..95247ff 100644 --- a/common/src/main/ets/utils/ConfigData.ets +++ b/common/src/main/ets/utils/ConfigData.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + class ConfigData { ONE_SECOND_TIME = 1000; ONE_MINUTE_TIME = 60000; @@ -25,7 +26,6 @@ class ConfigData { HOUR_SELECT = 100; MINUTE_SELECT = 60; SECOND_SELECT = 60; - FONT_WEIGHT = 500; NOTIFY_INTERVAL_MS = 50; STANDARD_SIZE = 280; DIALS_CENTER_OFFSET_X = 1 / 2; diff --git a/common/src/main/ets/utils/LogUtil.ts b/common/src/main/ets/utils/LogUtil.ts index 054bcfc..a6494c4 100644 --- a/common/src/main/ets/utils/LogUtil.ts +++ b/common/src/main/ets/utils/LogUtil.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import HiLog from "@ohos.hilog" + +import HiLog from "@ohos.hilog"; const DOMAIN = 0x0500; -const TAG = "[Clock]" +const TAG = "[Clock]"; /** * log package tool class diff --git a/common/src/main/ets/utils/TimerUtil.ets b/common/src/main/ets/utils/TimerUtil.ets index 42e7da0..d97fe7c 100644 --- a/common/src/main/ets/utils/TimerUtil.ets +++ b/common/src/main/ets/utils/TimerUtil.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,44 +12,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import ConfigData from "./ConfigData" + +import ConfigData from "./ConfigData"; export class TimerUtil { /** * Time format conversion + * * @param timestamp */ timeFormat(timestamp: number) { if (timestamp <= 0) { - return "00:00.00" + return "00:00.00"; } - let timeStr = "" - let day = Math.floor(timestamp / ConfigData.ONE_DAY_TIME) + let timeStr = ""; + let day = Math.floor(timestamp / ConfigData.ONE_DAY_TIME); if (day > 0) { - timeStr += this.addZero(day) + ":" + timeStr += this.addZero(day) + ":"; } - let hour = Math.floor(timestamp % ConfigData.ONE_DAY_TIME / ConfigData.ONE_HOUR_TIME) + let hour = Math.floor(timestamp % ConfigData.ONE_DAY_TIME / ConfigData.ONE_HOUR_TIME); if (hour > 0 || day > 0) { - timeStr += this.addZero(hour) + ":" + timeStr += this.addZero(hour) + ":"; } - let min = Math.floor(timestamp % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME) - timeStr += this.addZero(min) + ":" - let sec = Math.floor(timestamp % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME) - timeStr += this.addZero(sec) + "." - let mSec = Math.floor(timestamp % ConfigData.ONE_SECOND_TIME / 10) - timeStr += this.addZero(mSec) - return timeStr + let min = Math.floor(timestamp % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME); + timeStr += this.addZero(min) + ":"; + let sec = Math.floor(timestamp % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME); + timeStr += this.addZero(sec) + "."; + let mSec = Math.floor(timestamp % ConfigData.ONE_SECOND_TIME / 10); + timeStr += this.addZero(mSec); + return timeStr; } /** * If the number is less than 10, add "0". + * * @param num */ addZero(num) { - return (num < 10 ? "0" + num : num).toString() + return (num < 10 ? "0" + num : num).toString(); } } -let mTimerUtil = new TimerUtil() +let mTimerUtil = new TimerUtil(); -export default mTimerUtil as TimerUtil \ No newline at end of file +export default mTimerUtil as TimerUtil; \ No newline at end of file diff --git a/feature/countdown/index.ets b/feature/countdown/index.ets index ab64a86..e6f2316 100644 --- a/feature/countdown/index.ets +++ b/feature/countdown/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,8 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { CountdownView } from './src/main/ets/components/CountdownView' -export { TimeSelectView } from './src/main/ets/components/TimeSelectView' +export { CountdownView } from './src/main/ets/components/CountdownView'; -export { CountdownController, CountdownState } from './src/main/ets/controller/CountdownController' \ No newline at end of file +export { TimeSelectView } from './src/main/ets/components/TimeSelectView'; + +export { CountdownController, CountdownState } from './src/main/ets/controller/CountdownController'; \ No newline at end of file diff --git a/feature/countdown/src/main/ets/components/CountdownView.ets b/feature/countdown/src/main/ets/components/CountdownView.ets index 3e188db..619de09 100644 --- a/feature/countdown/src/main/ets/components/CountdownView.ets +++ b/feature/countdown/src/main/ets/components/CountdownView.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,89 +12,92 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { CountdownState } from '../controller/CountdownController' import { ConfigData } from '@ohos/common' @Component export struct CountdownView { - private viewSize: number = 40 - private context: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) - @Prop totalTime: number - @Prop currentTime: number - @State state: CountdownState = CountdownState.IDLE - private normalColor: string = '#007DFF' - private originRadius: number = 8 - private shadowOffset: number = 2.5 - private shadowColor: string = '#1400001E' - private scaleWidth: number = 2.5 - private scaleHeight: number = 16 - private scalePadding: number = 10.5 - private pointerOffset: number = 13.5 + private viewSize: number = 40; + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }); + private normalColor: string = '#007DFF'; + private originRadius: number = 8; + private shadowOffset: number = 2.5; + private shadowColor: string = '#1400001E'; + private scaleWidth: number = 2.5; + private scaleHeight: number = 16; + private scalePadding: number = 10.5; + private pointerOffset: number = 13.5; + private scaleBackgroundColor: string = '#66182431'; + private times: number = 2; + @Prop totalTime: number; + @Prop currentTime: number; + @Prop state: CountdownState; /** * Draw CountdownView. */ - private draw(): void{ - this.context.clearRect(0, 0, this.viewSize, this.viewSize) + private draw(): void { + this.context.clearRect(0, 0, this.viewSize, this.viewSize); - this.drawDials() - this.drawPointer(this.totalTime, this.currentTime) + this.drawDials(); + this.drawPointer(this.totalTime, this.currentTime); } /** * Draw origin circle and tick marks. */ - private drawDials(): void{ - this.context.save() - this.context.beginPath() - this.context.fillStyle = this.normalColor - this.context.arc(this.viewSize / 2, this.viewSize / 2, this.originRadius, 0, Math.PI * 2) - this.context.fill() - this.context.shadowBlur = this.originRadius * 2 + this.shadowOffset - this.context.shadowColor = this.shadowColor - this.context.restore() + private drawDials(): void { + this.context.save(); + this.context.beginPath(); + this.context.fillStyle = this.normalColor; + this.context.arc(this.viewSize / this.times, this.viewSize / this.times, this.originRadius, 0, Math.PI * this.times); + this.context.fill(); + this.context.shadowBlur = this.originRadius * this.times + this.shadowOffset; + this.context.shadowColor = this.shadowColor; + this.context.restore(); for (let n = 0; n < ConfigData.SCALE_NUM; n++) { - var theta = n * (Math.PI * 2) / ConfigData.SCALE_NUM - this.context.save() - this.context.lineWidth = this.scaleWidth - this.context.beginPath() - var x_move = (this.viewSize / 2 - this.scalePadding) * Math.sin(theta) + this.viewSize / 2 - var y_move = -(this.viewSize / 2 - this.scalePadding) * Math.cos(theta) + this.viewSize / 2 - var x_to = (this.viewSize / 2 - (this.scalePadding + this.scaleHeight)) * Math.sin(theta) + this.viewSize / 2 - var y_to = -(this.viewSize / 2 - (this.scalePadding + this.scaleHeight)) * Math.cos(theta) + this.viewSize / 2 + var theta = n * (Math.PI * this.times) / ConfigData.SCALE_NUM; + this.context.save(); + this.context.lineWidth = this.scaleWidth; + this.context.beginPath(); + var x_move = (this.viewSize / this.times - this.scalePadding) * Math.sin(theta) + this.viewSize / this.times; + var y_move = -(this.viewSize / this.times - this.scalePadding) * Math.cos(theta) + this.viewSize / this.times; + var x_to = (this.viewSize / this.times - (this.scalePadding + this.scaleHeight)) * Math.sin(theta) + this.viewSize / this.times; + var y_to = -(this.viewSize / this.times - (this.scalePadding + this.scaleHeight)) * Math.cos(theta) + this.viewSize / this.times; this.context.strokeStyle = (this.state == CountdownState.RUNNING || this.state == CountdownState.PAUSED) && (this.currentTime / this.totalTime > n / ConfigData.SCALE_NUM) && n ? 'rgb(' + Math.ceil(ConfigData.COLOR_R - (ConfigData.COLOR_R / ConfigData.SCALE_NUM * n)) + ',' + Math.ceil(ConfigData.COLOR_G_START - (ConfigData.COLOR_G_START - ConfigData.COLOR_G_END) / ConfigData.SCALE_NUM * n) + ',' + ConfigData.COLOR_B + ')' : - '#66182431' - this.context.moveTo(x_move, y_move) - this.context.lineTo(x_to, y_to) - this.context.stroke() - this.context.restore() + this.scaleBackgroundColor; + this.context.moveTo(x_move, y_move); + this.context.lineTo(x_to, y_to); + this.context.stroke(); + this.context.restore(); } } /** * Draw pointer. */ - private drawPointer(totalTime: number, currentTime: number): void{ - this.context.save() - this.context.strokeStyle = this.normalColor - this.context.shadowBlur = this.scaleWidth + this.shadowOffset - this.context.shadowColor = this.shadowColor - var theta = totalTime ? currentTime / totalTime * Math.PI * 2 : 0 - this.context.beginPath() - this.context.lineWidth = this.scaleWidth - var x_move = (this.viewSize / 2 - this.scalePadding) * Math.sin(theta) + this.viewSize / 2 - var y_move = -(this.viewSize / 2 - this.scalePadding) * Math.cos(theta) + this.viewSize / 2 - var x_to = -(this.originRadius + this.pointerOffset) * Math.sin(theta) + this.viewSize / 2 - var y_to = (this.originRadius + this.pointerOffset) * Math.cos(theta) + this.viewSize / 2 - this.context.moveTo(x_move, y_move) - this.context.lineTo(x_to, y_to) - this.context.stroke() - this.context.restore() + private drawPointer(totalTime: number, currentTime: number): void { + this.context.save(); + this.context.strokeStyle = this.normalColor; + this.context.shadowBlur = this.scaleWidth + this.shadowOffset; + this.context.shadowColor = this.shadowColor; + var theta = totalTime ? currentTime / totalTime * Math.PI * this.times : 0; + this.context.beginPath(); + this.context.lineWidth = this.scaleWidth; + var x_move = (this.viewSize / this.times - this.scalePadding) * Math.sin(theta) + this.viewSize / this.times; + var y_move = -(this.viewSize / this.times - this.scalePadding) * Math.cos(theta) + this.viewSize / this.times; + var x_to = -(this.originRadius + this.pointerOffset) * Math.sin(theta) + this.viewSize / this.times; + var y_to = (this.originRadius + this.pointerOffset) * Math.cos(theta) + this.viewSize / this.times; + this.context.moveTo(x_move, y_move); + this.context.lineTo(x_to, y_to); + this.context.stroke(); + this.context.restore(); } build() { @@ -106,6 +109,6 @@ export struct CountdownView { .shadow({ radius: $r("app.float.radius_value_26_5"), color: this.shadowColor }) .onReady(() => { this.draw() - }) + }); } } \ No newline at end of file diff --git a/feature/countdown/src/main/ets/components/TimeSelectView.ets b/feature/countdown/src/main/ets/components/TimeSelectView.ets index cc2f920..3f33dcd 100644 --- a/feature/countdown/src/main/ets/components/TimeSelectView.ets +++ b/feature/countdown/src/main/ets/components/TimeSelectView.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,23 +13,22 @@ * limitations under the License. */ -import { ConfigData, LogUtil } from '@ohos/common' +import { ConfigData, LogUtil } from '@ohos/common'; -const TAG = "TimeSelectView : " +const TAG = 'TimeSelectView : '; @Component export struct TimeSelectView { - private marginRight: number | Resource = $r("app.float.distance_30") - private dividerMargin: number | Resource = $r("app.float.distance_75") - private select: number = 0 - private hourRange: number[] = Array.from(new Array(ConfigData.HOUR_SELECT).keys()) - private minuteRange: number[] = Array.from(new Array(ConfigData.MINUTE_SELECT).keys()) - private secondRange: number[] = Array.from(new Array(ConfigData.SECOND_SELECT).keys()) - @Link hour: string - @Link minute: string - @Link second: string - private callBack?: () => void - private sca: number = 1 + private marginRight: number | Resource = $r("app.float.distance_30"); + private dividerMargin: number | Resource = $r("app.float.distance_75"); + private hourRange: number[] = Array.from(new Array(ConfigData.HOUR_SELECT).keys()); + private minuteRange: number[] = Array.from(new Array(ConfigData.MINUTE_SELECT).keys()); + private secondRange: number[] = Array.from(new Array(ConfigData.SECOND_SELECT).keys()); + private callBack?: () => void; + private sca: number = 1; + @Link hour: string; + @Link minute: string; + @Link second: string; build() { Flex({ justifyContent: FlexAlign.Center, alignContent: FlexAlign.Start }) { @@ -42,7 +41,7 @@ export struct TimeSelectView { marginRight: this.marginRight, value: $hour, onChangCallBack: this.callBack - }) + }); TimeSelectItem({ fruits: this.convert(this.minuteRange), @@ -51,7 +50,7 @@ export struct TimeSelectView { marginRight: this.marginRight, value: $minute, onChangCallBack: this.callBack - }) + }); TimeSelectItem({ fruits: this.convert(this.secondRange), @@ -60,18 +59,24 @@ export struct TimeSelectView { marginRight: this.marginRight, value: $second, onChangCallBack: this.callBack - }) + }); } Divider() .strokeWidth(1) .color($r("app.color.divider_color")) - .margin({ left: this.dividerMargin, right: this.dividerMargin, top: $r("app.float.distance_35") }) + .margin({ + left: this.dividerMargin, + right: this.dividerMargin, top: $r("app.float.distance_35") + }); Divider() .strokeWidth(1) .color($r("app.color.divider_color")) - .margin({ left: this.dividerMargin, right: this.dividerMargin, bottom: $r("app.float.distance_78") }) + .margin({ + left: this.dividerMargin, + right: this.dividerMargin, bottom: $r("app.float.distance_78") + }); } } .scale({ x: this.sca, y: this.sca }) @@ -81,25 +86,24 @@ export struct TimeSelectView { * Make up 0 if less than 10. */ private convert(char: Array) { - let str = [] + let str = []; for (let i = 0; i < char.length; i++) { - str.push((char[i] > 9 ? "" : "0") + char[i]) + str.push((char[i] > 9 ? '' : '0') + char[i]); } - return str + return str; } } @Component struct TimeSelectItem { - private fruits: string[] = [] - private select: number = 0 - private text: ResourceStr = '' - private isVisibility: boolean = true - private marginRight: number | Resource = $r("app.float.distance_30") - @Link value: string - private componentWidth: number | Resource = $r("app.float.wh_value_40") - private componentHeight: number | Resource = $r("app.float.wh_value_160") - private onChangCallBack?: () => void + private fruits: string[] = []; + private text: ResourceStr = ''; + private isVisibility: boolean = true; + private marginRight: number | Resource = $r("app.float.distance_30"); + private componentWidth: number | Resource = $r("app.float.wh_value_40"); + private componentHeight: number | Resource = $r("app.float.wh_value_160"); + private onChangCallBack?: () => void; + @Link value: string; build() { Row() { @@ -109,18 +113,18 @@ struct TimeSelectItem { .width(this.componentWidth) .height(this.componentHeight) .onChange((value: string, index: number) => { - this.value = value - this.onChangCallBack() - LogUtil.info(`${TAG} Picker item changed, value: ${value}, index: ${index} `) - }) - Text(this.text).fontSize($r("app.float.font_24")).fontWeight(ConfigData.FONT_WEIGHT).height($r("app.float.wh_value_21_5")) - }.margin({ right: this.isVisibility ? this.marginRight : $r("app.float.distance_0") }) + this.value = value; + this.onChangCallBack(); + LogUtil.info(`${TAG} Picker item changed, value: ${value}, index: ${index} `); + }); + Text(this.text).fontSize($r("app.float.font_24")).fontWeight(FontWeight.Regular).height($r("app.float.wh_value_21_5")) + }.margin({ right: this.isVisibility ? this.marginRight : $r("app.float.distance_0") }); Column() { - Text(":").fontSize($r("app.float.font_40")).fontWeight(ConfigData.FONT_WEIGHT).fontColor($r("app.color.font_color")) - Text("").fontSize($r("app.float.font_24")).fontWeight(ConfigData.FONT_WEIGHT).height($r("app.float.wh_value_21_5")) + Text(':').fontSize($r("app.float.font_40")).fontWeight(FontWeight.Regular).fontColor($r("app.color.font_color")); + Text('').fontSize($r("app.float.font_24")).fontWeight(FontWeight.Regular).height($r("app.float.wh_value_21_5")); }.margin({ right: this.marginRight }) - .visibility(this.isVisibility ? Visibility.Visible : Visibility.None) + .visibility(this.isVisibility ? Visibility.Visible : Visibility.None); } } } \ No newline at end of file diff --git a/feature/countdown/src/main/ets/controller/CountdownController.ets b/feature/countdown/src/main/ets/controller/CountdownController.ets index a702b32..05e3d3c 100644 --- a/feature/countdown/src/main/ets/controller/CountdownController.ets +++ b/feature/countdown/src/main/ets/controller/CountdownController.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import dataStorage from '@ohos.data.preferences'; -import { ConfigData, LogUtil } from '@ohos/common' +import { ConfigData, LogUtil } from '@ohos/common'; -const TAG = "CountdownController : " +const TAG = 'CountdownController : '; export enum CountdownState { /** @@ -50,183 +51,188 @@ export class CountdownController { private notifierId: number = 0; private startTimestamp: number = 0; private startAnchorTimeMs: number = 0; - state: CountdownState = CountdownState.IDLE; - timeUpdateListener: (currentTimeMs: number, totalTimeMs: number) => void = undefined - stateUpdateListener: (CountdownState) => void = undefined; + private state: CountdownState = CountdownState.IDLE; + private timeUpdateListener: (currentTimeMs: number, totalTimeMs: number) => void = undefined; + private stateUpdateListener: (CountdownState) => void = undefined; private preferences = null; + private totalTimeMsStr: string = 'totalTimeMs'; + private countdownStr: string = 'Countdown'; + private countdownStateStr: string = 'CountdownState'; + private startAnchorTimeMsStr: string = 'startAnchorTimeMs'; + private startTimestampStr: string = 'startTimestamp'; /** * Set time listener. */ - setTimeUpdateListener(listener: (currentTimeMs: number, totalTimeMs: number) => void) { + public setTimeUpdateListener(listener: (currentTimeMs: number, totalTimeMs: number) => void) { this.timeUpdateListener = listener; } /** * Set countdownState listener. */ - setStateUpdateListener(listener: (CountdownState) => void) { + public setStateUpdateListener(listener: (CountdownState) => void) { this.stateUpdateListener = listener; } /** * Set countdown time. */ - setTime(totalTimeMs: number) { - LogUtil.info(`${TAG} set countdown time. `) + public setTime(totalTimeMs: number) { + LogUtil.info(`${TAG} set countdown time. `); if (this.state != CountdownState.IDLE && this.state != CountdownState.PREPARED) { - throw ('only support set time before start!') + throw ('only support set time before start!'); } if (totalTimeMs < 0) { - throw ('illegal totalTimeMs!') + throw ('illegal totalTimeMs!'); } this.totalTimeMs = totalTimeMs; - LogUtil.info(`${TAG} countdown totalTime: ${this.totalTimeMs}ms. `) + LogUtil.info(`${TAG} countdown totalTime: ${this.totalTimeMs}ms. `); this.startAnchorTimeMs = this.totalTimeMs; - this.updateData('totalTimeMs', this.totalTimeMs); - this.updateData('startAnchorTimeMs', this.startAnchorTimeMs); + this.updateData(this.totalTimeMsStr, this.totalTimeMs); + this.updateData(this.startAnchorTimeMsStr, this.startAnchorTimeMs); this.currentTimeMs = totalTimeMs; - this.notifyTimeChanges() + this.notifyTimeChanges(); if (this.state == CountdownState.IDLE && totalTimeMs > 0) { - this.state = CountdownState.PREPARED - this.updateData('CountdownState', this.state); + this.state = CountdownState.PREPARED; + this.updateData(this.countdownStateStr, this.state); this.notifyStateChanges(); } else if (this.state == CountdownState.PREPARED && totalTimeMs == 0) { - this.state = CountdownState.IDLE - this.updateData('CountdownState', this.state); + this.state = CountdownState.IDLE; + this.updateData(this.countdownStateStr, this.state); this.notifyStateChanges(); } } private notifyTimeChanges() { if (this.timeUpdateListener) { - this.timeUpdateListener(this.currentTimeMs, this.totalTimeMs) + this.timeUpdateListener(this.currentTimeMs, this.totalTimeMs); } } private notifyStateChanges() { if (this.stateUpdateListener) { - this.stateUpdateListener(this.state) + this.stateUpdateListener(this.state); } } /** * Countdown start. */ - start() { - LogUtil.info(`${TAG} countdown start. `) + public start() { + LogUtil.info(`${TAG} countdown start. `); if (this.state != CountdownState.PREPARED && this.state != CountdownState.PAUSED) { return; } - LogUtil.info(`${TAG} countdown start in. `) + LogUtil.info(`${TAG} countdown start in. `); if (this.totalTimeMs > 0 && this.currentTimeMs > 0) { if (this.currentTimeMs >= ConfigData.NOTIFY_INTERVAL_MS) { this.startTimestamp = new Date().getTime(); - this.updateData('startTimestamp', this.startTimestamp); + this.updateData(this.startTimestampStr, this.startTimestamp); this.countdown(); } else { this.lastRefresh(); } } this.state = CountdownState.RUNNING; - this.updateData('CountdownState', this.state); - this.notifyStateChanges() + this.updateData(this.countdownStateStr, this.state); + this.notifyStateChanges(); } /** * Countdown start-up. */ - countdown() { - LogUtil.info(`${TAG} countdown start up. `) + public countdown() { + LogUtil.info(`${TAG} countdown start up. `); this.notifierId = setInterval(() => { let timestamp = new Date().getTime(); - this.currentTimeMs = this.startAnchorTimeMs - (timestamp - this.startTimestamp) + this.currentTimeMs = this.startAnchorTimeMs - (timestamp - this.startTimestamp); if (this.currentTimeMs <= 0) { this.currentTimeMs = 0; - clearInterval(this.notifierId) - this.notifierId = 0 + clearInterval(this.notifierId); + this.notifierId = 0; } else if (this.currentTimeMs < ConfigData.NOTIFY_INTERVAL_MS) { - clearInterval(this.notifierId) - this.notifierId = 0 + clearInterval(this.notifierId); + this.notifierId = 0; this.lastRefresh(); } - this.notifyTimeChanges() + this.notifyTimeChanges(); if (this.currentTimeMs == 0) { - this.state = CountdownState.STOPPED - this.updateData('CountdownState', this.state); - this.notifyStateChanges() + this.state = CountdownState.STOPPED; + this.updateData(this.countdownStateStr, this.state); + this.notifyStateChanges(); } - }, ConfigData.NOTIFY_INTERVAL_MS) + }, ConfigData.NOTIFY_INTERVAL_MS); } /** * Countdown reStart. */ - reStart() { + public reStart() { LogUtil.info(`${TAG} countdown reStart. `) if (this.state == CountdownState.STOPPED) { - this.state = CountdownState.PREPARED - this.updateData('CountdownState', this.state); - this.notifyStateChanges() + this.state = CountdownState.PREPARED; + this.updateData(this.countdownStateStr, this.state); + this.notifyStateChanges(); } } /** * Countdown lastRefresh. */ - lastRefresh() { - LogUtil.info(`${TAG} countdown lastRefresh. `) + public lastRefresh() { + LogUtil.info(`${TAG} countdown lastRefresh. `); setTimeout(() => { this.currentTimeMs = 0; - this.notifyTimeChanges() - this.state = CountdownState.STOPPED - this.updateData('CountdownState', this.state); - this.notifyStateChanges() - }, this.currentTimeMs) + this.notifyTimeChanges(); + this.state = CountdownState.STOPPED; + this.updateData(this.countdownStateStr, this.state); + this.notifyStateChanges(); + }, this.currentTimeMs); } /** * Countdown pause. */ - pause() { - LogUtil.info(`${TAG} countdown pause. `) + public pause() { + LogUtil.info(`${TAG} countdown pause. `); if (this.state != CountdownState.RUNNING) { return; } - LogUtil.info(`${TAG} countdown pause in. `) + LogUtil.info(`${TAG} countdown pause in. `); let timestamp = new Date().getTime(); clearInterval(this.notifierId); - this.startAnchorTimeMs = this.startAnchorTimeMs - (timestamp - this.startTimestamp) - this.updateData('startAnchorTimeMs', this.startAnchorTimeMs); + this.startAnchorTimeMs = this.startAnchorTimeMs - (timestamp - this.startTimestamp); + this.updateData(this.startAnchorTimeMsStr, this.startAnchorTimeMs); this.notifierId = 0; this.state = CountdownState.PAUSED; - this.updateData('CountdownState', this.state); - this.notifyStateChanges() + this.updateData(this.countdownStateStr, this.state); + this.notifyStateChanges(); } /** * Countdown reset. */ - reset() { - LogUtil.info(`${TAG} countdown reset. `) + public reset() { + LogUtil.info(`${TAG} countdown reset. `); if (this.state == CountdownState.IDLE) { return; } - LogUtil.info(`${TAG} countdown reset in. `) + LogUtil.info(`${TAG} countdown reset in. `); if (this.notifierId != 0) { - clearInterval(this.notifierId) + clearInterval(this.notifierId); this.notifierId = 0; } - this.totalTimeMs = 0 - this.updateData('totalTimeMs', this.totalTimeMs); - this.currentTimeMs = 0 + this.totalTimeMs = 0; + this.updateData(this.totalTimeMsStr, this.totalTimeMs); + this.currentTimeMs = 0; this.startTimestamp = 0; - this.updateData('startTimestamp', this.startTimestamp); + this.updateData(this.startTimestampStr, this.startTimestamp); this.startAnchorTimeMs = 0; this.notifyTimeChanges(); - this.state = CountdownState.IDLE - this.updateData('CountdownState', this.state); - this.notifyStateChanges() + this.state = CountdownState.IDLE; + this.updateData(this.countdownStateStr, this.state); + this.notifyStateChanges(); } /** @@ -234,7 +240,7 @@ export class CountdownController { */ public async getPreferences() { if (this.preferences) { - this.preferences = await dataStorage.getPreferences(globalThis.abilityContext, 'Countdown'); + this.preferences = await dataStorage.getPreferences(globalThis.abilityContext, this.countdownStr); } } @@ -243,17 +249,17 @@ export class CountdownController { */ public async getData() { await this.getPreferences(); - this.state = await this.preferences.get('CountdownState', CountdownState.IDLE); - this.startTimestamp = await this.preferences.get('startTimestamp', 0); - this.totalTimeMs = await this.preferences.get('totalTimeMs', 0); - this.startAnchorTimeMs = await this.preferences.get('startAnchorTimeMs', 0); + this.state = await this.preferences.get(this.countdownStateStr, CountdownState.IDLE); + this.startTimestamp = await this.preferences.get(this.startTimestampStr, 0); + this.totalTimeMs = await this.preferences.get(this.totalTimeMsStr, 0); + this.startAnchorTimeMs = await this.preferences.get(this.startAnchorTimeMsStr, 0); if (this.state == CountdownState.PREPARED) { this.currentTimeMs = this.totalTimeMs; } else if (this.state == CountdownState.RUNNING) { this.countdown(); } else if (this.state == CountdownState.PAUSED) { - this.currentTimeMs = this.startAnchorTimeMs + this.currentTimeMs = this.startAnchorTimeMs; } this.notifyStateChanges(); this.notifyTimeChanges(); diff --git a/feature/timer/index.ets b/feature/timer/index.ets index 95bd1ed..0f2258b 100644 --- a/feature/timer/index.ets +++ b/feature/timer/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { TimerView } from './src/main/ets/components/TimerView' -export { TimerController, TimerState } from './src/main/ets/controller/TimerController' +export { TimerView } from './src/main/ets/components/TimerView'; + +export { TimerController, TimerState } from './src/main/ets/controller/TimerController'; diff --git a/feature/timer/src/main/ets/components/TimerView.ets b/feature/timer/src/main/ets/components/TimerView.ets index 3aa694e..6ff76fe 100644 --- a/feature/timer/src/main/ets/components/TimerView.ets +++ b/feature/timer/src/main/ets/components/TimerView.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,33 +13,33 @@ * limitations under the License. */ -import { ConfigData } from '@ohos/common' +import { ConfigData } from '@ohos/common'; @Component export struct TimerView { - private sSize: number = vp2px(ConfigData.STANDARD_SIZE) - @Prop currentTime: number - private mSize: number = 0 - private dialsContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) - private secondContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) - private minutesContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) + @Prop currentTime: number; + private sSize: number = vp2px(ConfigData.STANDARD_SIZE); + private mSize: number = 0; + private dialsContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }); + private secondContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }); + private minutesContext: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }); // Second disc radius - private sRadius: number = 0 + private sRadius: number = 0; // Points set radius - private mRadius: number = 0 + private mRadius: number = 0; // scale - private mScale: number = 1 + private mScale: number = 1; // Second hand time scale value - private times: Array = [60, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,] + private times: Array = [60, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]; // Minute hand time scale value - private minTimes: Array = [30, 5, 10, 15, 20, 25] + private minTimes: Array = [30, 5, 10, 15, 20, 25]; aboutToAppear() { - this.mScale = this.sSize / ConfigData.STANDARD_SIZE - this.mSize = this.sSize / 4 + this.mScale = this.sSize / ConfigData.STANDARD_SIZE; + this.mSize = this.sSize / 4; // Get the radius - this.sRadius = this.sSize / 2 - ConfigData.SECOND_DISTANCE * this.mScale - this.mRadius = this.mSize / 2 - ConfigData.MINUTE_DISTANCE * this.mScale + this.sRadius = this.sSize / 2 - ConfigData.SECOND_DISTANCE * this.mScale; + this.mRadius = this.mSize / 2 - ConfigData.MINUTE_DISTANCE * this.mScale; } build() { @@ -53,19 +53,19 @@ export struct TimerView { }) .backgroundColor($r("app.color.background_color_white")) .borderRadius(this.sSize / 2) - .shadow({ radius: ConfigData.SHADOW_RADIUS * this.mScale, color: $r("app.color.shadow_color") }) + .shadow({ radius: ConfigData.SHADOW_RADIUS * this.mScale, color: $r("app.color.shadow_color") }); Canvas(this.minutesContext) .height(this.sSize) .aspectRatio(1.0) .onReady(() => { this.drawMinutes(this.currentTime % (60 * 60 * 1000) / (60 * 1000)) - }) + }); Canvas(this.secondContext) .height(this.sSize) .aspectRatio(1.0) .onReady(() => { this.drawSecond(this.currentTime % (60 * 1000) / 1000) - }) + }); } } .justifyContent(FlexAlign.Center) @@ -76,21 +76,21 @@ export struct TimerView { * Draw a Second hand * @param second */ - private drawSecond(second: number): void{ - this.secondContext.clearRect(0, 0, this.sSize, this.sSize) - this.secondContext.lineCap = 'round' - this.secondContext.save() - this.secondContext.strokeStyle = ConfigData.SECOND_HAND_COLOR + private drawSecond(second: number): void { + this.secondContext.clearRect(0, 0, this.sSize, this.sSize); + this.secondContext.lineCap = 'round'; + this.secondContext.save(); + this.secondContext.strokeStyle = ConfigData.SECOND_HAND_COLOR; // Pointer Angle The second hand is divided into 60 parts let theta = second * 2 * Math.PI / 60; - this.secondContext.beginPath() + this.secondContext.beginPath(); // A pointer to draw let x_move = this.sRadius * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_move = -this.sRadius * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; let x_to = -(ConfigData.SECOND_POINTER_OVER * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_to = (ConfigData.SECOND_POINTER_OVER * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; - this.secondContext.lineWidth = ConfigData.SECOND_HAND_WIDTH * this.mScale + this.secondContext.lineWidth = ConfigData.SECOND_HAND_WIDTH * this.mScale; this.secondContext.moveTo(x_move, y_move); this.secondContext.lineTo(x_to, y_to); this.secondContext.stroke(); @@ -101,20 +101,20 @@ export struct TimerView { * Draw a minute hand * @param minutes */ - private drawMinutes(minutes: number): void{ - this.minutesContext.clearRect(0, 0, this.sSize, this.sSize) - this.minutesContext.lineCap = 'round' - this.minutesContext.save() + private drawMinutes(minutes: number): void { + this.minutesContext.clearRect(0, 0, this.sSize, this.sSize); + this.minutesContext.lineCap = 'round'; + this.minutesContext.save(); // Pointer Angle The minute hand is divided into 30 parts let theta = minutes * 2 * Math.PI / 30; - this.minutesContext.beginPath() + this.minutesContext.beginPath(); // Start position of scale let x_move = (this.mRadius - ConfigData.MINUTE_POINTER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_move = -(this.mRadius - ConfigData.MINUTE_POINTER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; // End of scale position let x_to = (ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_to = (-ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; - this.minutesContext.lineWidth = ConfigData.MINUTE_TICK_MARK_WIDTH * this.mScale + this.minutesContext.lineWidth = ConfigData.MINUTE_TICK_MARK_WIDTH * this.mScale; this.minutesContext.moveTo(x_move, y_move); this.minutesContext.lineTo(x_to, y_to); this.minutesContext.stroke(); @@ -122,37 +122,37 @@ export struct TimerView { } private drawDials() { - this.dialsContext.clearRect(0, 0, this.sSize, this.sSize) - this.drawSecDials() - this.drawMinDials() + this.dialsContext.clearRect(0, 0, this.sSize, this.sSize); + this.drawSecDials(); + this.drawMinDials(); } /** * Draw the second hand disc */ - private drawSecDials(): void{ - this.dialsContext.lineCap = 'round' + private drawSecDials(): void { + this.dialsContext.lineCap = 'round'; // Draw the origin - this.dialsContext.save() - this.dialsContext.fillStyle = ConfigData.SECOND_HAND_COLOR - this.dialsContext.beginPath() + this.dialsContext.save(); + this.dialsContext.fillStyle = ConfigData.SECOND_HAND_COLOR; + this.dialsContext.beginPath(); - this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y, ConfigData.SECOND_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2) - this.dialsContext.fill() - this.dialsContext.restore() - this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y, ConfigData.SECOND_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2); + this.dialsContext.fill(); + this.dialsContext.restore(); + this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR; // Font style - this.dialsContext.font = "normal 500 " + vp2px(ConfigData.SECOND_FONT_SIZE * this.mScale) + 'px' - this.dialsContext.textBaseline = "middle" - this.dialsContext.textAlign = "center" + this.dialsContext.font = "normal 500 " + vp2px(ConfigData.SECOND_FONT_SIZE * this.mScale) + 'px'; + this.dialsContext.textBaseline = "middle"; + this.dialsContext.textAlign = "center"; // Drawing scale for (let n = 0; n < 60; n++) { // Gets an Angle of 60 scales let theta = n * (Math.PI * 2) / 60; - this.dialsContext.save() + this.dialsContext.save(); // Setting the scale width - this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale - this.dialsContext.beginPath() + this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale; + this.dialsContext.beginPath(); // Start position of scale let x_move = this.sRadius * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_move = -this.sRadius * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; @@ -162,7 +162,7 @@ export struct TimerView { // Integral point calibration if (n % 5 == 0) { // The scale width of the hour - this.dialsContext.lineWidth = ConfigData.HOUR_TICK_MARK_WIDTH * this.mScale + this.dialsContext.lineWidth = ConfigData.HOUR_TICK_MARK_WIDTH * this.mScale; // End position of the mark on the hour x_to = (this.sRadius - ConfigData.HOUR_SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; y_to = -(this.sRadius - ConfigData.HOUR_SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; @@ -170,40 +170,40 @@ export struct TimerView { let x_time = (this.sRadius - ConfigData.HOUR_SECOND_TIMER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_time = -(this.sRadius - ConfigData.HOUR_SECOND_TIMER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; // Plot the hour - this.dialsContext.fillText(this.times[n / 5] + '', x_time, y_time) + this.dialsContext.fillText(this.times[n / 5] + '', x_time, y_time); } // Draw the scale - this.dialsContext.moveTo(x_move, y_move) - this.dialsContext.lineTo(x_to, y_to) - this.dialsContext.stroke() - this.dialsContext.restore() + this.dialsContext.moveTo(x_move, y_move); + this.dialsContext.lineTo(x_to, y_to); + this.dialsContext.stroke(); + this.dialsContext.restore(); } } /** * Draw the minute hand dial */ - private drawMinDials(): void{ + private drawMinDials(): void { // Draw the origin - this.dialsContext.save() - this.dialsContext.beginPath() - this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2) - this.dialsContext.fill() - this.dialsContext.fillStyle = ConfigData.CIRCLE_WIDTH_COLOR - this.dialsContext.beginPath() - this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CENTER_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2) - this.dialsContext.fill() - this.dialsContext.restore() + this.dialsContext.save(); + this.dialsContext.beginPath(); + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2); + this.dialsContext.fill(); + this.dialsContext.fillStyle = ConfigData.CIRCLE_WIDTH_COLOR; + this.dialsContext.beginPath(); + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CENTER_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2); + this.dialsContext.fill(); + this.dialsContext.restore(); // Font style - this.dialsContext.font = "normal 400 " + vp2px(ConfigData.MINUTE_FONT_SIZE * this.mScale) + 'px' + this.dialsContext.font = "normal 400 " + vp2px(ConfigData.MINUTE_FONT_SIZE * this.mScale) + 'px'; // Drawing scale for (let n = 0; n < 30; n++) { - this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR + this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR; let theta = n * (Math.PI * 2) / 30; - this.dialsContext.save() + this.dialsContext.save(); // Scale width - this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale - this.dialsContext.beginPath() + this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale; + this.dialsContext.beginPath(); // Start position of scale let x_move = this.mRadius * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_move = -this.mRadius * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; @@ -212,18 +212,18 @@ export struct TimerView { let y_to = -(this.mRadius - ConfigData.MINUTE_TICK_MARK_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; // Integral point calibration if (n % 5 == 0) { - this.dialsContext.strokeStyle = ConfigData.HOUR_TICK_MARK_COLOR + this.dialsContext.strokeStyle = ConfigData.HOUR_TICK_MARK_COLOR; // Time position on the hour let x_time = (this.mRadius - ConfigData.HOUR_MINUTE_TIMER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_time = -(this.mRadius - ConfigData.HOUR_MINUTE_TIMER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; // Plot the hour - this.dialsContext.fillText(this.minTimes[n / 5] + '', x_time, y_time) + this.dialsContext.fillText(this.minTimes[n / 5] + '', x_time, y_time); } // Draw the scale - this.dialsContext.moveTo(x_move, y_move) - this.dialsContext.lineTo(x_to, y_to) - this.dialsContext.stroke() - this.dialsContext.restore() + this.dialsContext.moveTo(x_move, y_move); + this.dialsContext.lineTo(x_to, y_to); + this.dialsContext.stroke(); + this.dialsContext.restore(); } } } diff --git a/feature/timer/src/main/ets/controller/TimerController.ets b/feature/timer/src/main/ets/controller/TimerController.ets index 34a2563..41e9099 100644 --- a/feature/timer/src/main/ets/controller/TimerController.ets +++ b/feature/timer/src/main/ets/controller/TimerController.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,10 +13,10 @@ * limitations under the License. */ -import { ConfigData, LogUtil } from '@ohos/common' +import { ConfigData, LogUtil } from '@ohos/common'; import data_preferences from '@ohos.data.preferences'; -const TAG = "TimerController : " +const TAG = "TimerController : "; export enum TimerState { /** @@ -35,125 +35,125 @@ export enum TimerState { export class TimerController { private currentTimeMs: number = 0; - private beforePauseTime: number = 0 + private beforePauseTime: number = 0; private state: TimerState = TimerState.IDLE; - private startTimestamp: number = 0 - private notifierId: number = -1 - private timeList: Array = [] - private lastTimeMs: number = 0 - private timeUpdateListener: (currentTimeMs: number) => void = undefined - private clockUpdateListener: (currentTimeMs: number) => void = undefined + private startTimestamp: number = 0; + private notifierId: number = -1; + private timeList: Array = []; + private lastTimeMs: number = 0; + private timeUpdateListener: (currentTimeMs: number) => void = undefined; + private clockUpdateListener: (currentTimeMs: number) => void = undefined; private stateUpdateListener: (TimerState) => void = undefined; private timeListUpdateListener: (timeList: Array, lastTimeMs: number) => void = undefined; - private preferences: data_preferences.Preferences = undefined + private preferences: data_preferences.Preferences = undefined; /** * Timer start */ public async start() { - LogUtil.info(`${TAG} timer start `) + LogUtil.info(`${TAG} timer start `); this.startTimestamp = new Date().getTime(); if (this.notifierId != -1) { - clearInterval(this.notifierId) - this.notifierId = -1 + clearInterval(this.notifierId); + this.notifierId = -1; } this.notifierId = setInterval(() => { let timestamp = new Date().getTime(); - this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp - this.notifyTimeChanges() - }, ConfigData.NOTIFY_INTERVAL_MS) + this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp; + this.notifyTimeChanges(); + }, ConfigData.NOTIFY_INTERVAL_MS); if (this.preferences) { - await this.preferences.put("startTimestamp", this.startTimestamp) + await this.preferences.put("startTimestamp", this.startTimestamp); } this.state = TimerState.RUNNING; - this.notifyStateChanges() + this.notifyStateChanges(); } /** * Timer pause */ public async pause() { - LogUtil.info(`${TAG} timer pause `) - clearInterval(this.notifierId) - this.beforePauseTime += new Date().getTime() - this.startTimestamp - this.currentTimeMs = this.beforePauseTime - this.notifyTimeChanges() - this.notifierId = -1 + LogUtil.info(`${TAG} timer pause `); + clearInterval(this.notifierId); + this.beforePauseTime += new Date().getTime() - this.startTimestamp; + this.currentTimeMs = this.beforePauseTime; + this.notifyTimeChanges(); + this.notifierId = -1; this.state = TimerState.PAUSED; if (this.preferences) { - await this.preferences.put("beforePauseTime", this.beforePauseTime) + await this.preferences.put("beforePauseTime", this.beforePauseTime); } - this.notifyTimeChanges() - this.notifyStateChanges() + this.notifyTimeChanges(); + this.notifyStateChanges(); } /** * Timer reset */ public reset() { - LogUtil.info(`${TAG} timer reset `) - this.beforePauseTime = 0 - this.startTimestamp = 0 - this.timeList = [] - this.lastTimeMs = 0 - this.notifierId = -1 - this.currentTimeMs = 0 + LogUtil.info(`${TAG} timer reset `); + this.beforePauseTime = 0; + this.startTimestamp = 0; + this.timeList = []; + this.lastTimeMs = 0; + this.notifierId = -1; + this.currentTimeMs = 0; this.state = TimerState.IDLE; - this.notifyTimeChanges() - this.notifyStateChanges() - this.notifyTimeListChanges() - this.preferences.clear() + this.notifyTimeChanges(); + this.notifyStateChanges(); + this.notifyTimeListChanges(); + this.preferences.clear(); } /** * Read the previous state from the preferences */ public async reload() { - LogUtil.info(`${TAG} Read the previous data `) - this.preferences = await data_preferences.getPreferences(globalThis.abilityContext, 'myClockStore') - this.state = await this.preferences.get("state", TimerState.IDLE) - this.lastTimeMs = await this.preferences.get("lastTimeMs", 0) - this.beforePauseTime = await this.preferences.get("beforePauseTime", 0) - this.startTimestamp = await this.preferences.get("startTimestamp", 0) - - let timeList = await this.preferences.get("timeList", 0) + LogUtil.info(`${TAG} Read the previous data `); + this.preferences = await data_preferences.getPreferences(globalThis.abilityContext, 'myClockStore'); + this.state = await this.preferences.get("state", TimerState.IDLE); + this.lastTimeMs = await this.preferences.get("lastTimeMs", 0); + this.beforePauseTime = await this.preferences.get("beforePauseTime", 0); + this.startTimestamp = await this.preferences.get("startTimestamp", 0); + + let timeList = await this.preferences.get("timeList", 0); if (timeList == 0) { - this.timeList = [] + this.timeList = []; } else { - this.timeList = > timeList + this.timeList = > timeList; } if (this.state == TimerState.RUNNING) { if (this.notifierId != -1) { - clearInterval(this.notifierId) - this.notifierId = -1 + clearInterval(this.notifierId); + this.notifierId = -1; } this.notifierId = setInterval(() => { let timestamp = new Date().getTime(); - this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp - this.notifyTimeChanges() - }, ConfigData.NOTIFY_INTERVAL_MS) + this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp; + this.notifyTimeChanges(); + }, ConfigData.NOTIFY_INTERVAL_MS); } else if (this.state == TimerState.PAUSED) { - this.currentTimeMs = this.beforePauseTime + this.currentTimeMs = this.beforePauseTime; } else { - this.reset() + this.reset(); } - this.notifyTimeChanges() + this.notifyTimeChanges(); if (this.timeList.length > 0) { - this.notifyTimeListChanges() + this.notifyTimeListChanges(); } - this.notifyStateChanges() + this.notifyStateChanges(); } /** * Recording the Current Time */ public writeTime() { - LogUtil.info(`${TAG} Recording time `) + LogUtil.info(`${TAG} Recording time `); let timestamp = new Date().getTime(); - this.lastTimeMs = Math.floor((this.beforePauseTime + timestamp - this.startTimestamp) / 10) * 10 - this.timeList.push(this.lastTimeMs) - this.notifyTimeListChanges() + this.lastTimeMs = Math.floor((this.beforePauseTime + timestamp - this.startTimestamp) / 10) * 10; + this.timeList.push(this.lastTimeMs); + this.notifyTimeListChanges(); } /** @@ -161,10 +161,10 @@ export class TimerController { */ private notifyTimeChanges() { if (this.timeUpdateListener) { - this.timeUpdateListener(this.currentTimeMs) + this.timeUpdateListener(this.currentTimeMs); } if (this.clockUpdateListener) { - this.clockUpdateListener(this.currentTimeMs) + this.clockUpdateListener(this.currentTimeMs); } } @@ -173,12 +173,12 @@ export class TimerController { */ private async notifyTimeListChanges() { if (this.timeListUpdateListener) { - this.timeListUpdateListener(this.timeList, this.lastTimeMs) + this.timeListUpdateListener(this.timeList, this.lastTimeMs); } if (this.preferences) { - await this.preferences.put("timeList", this.timeList) - await this.preferences.put("lastTimeMs", this.lastTimeMs) - this.flush() + await this.preferences.put("timeList", this.timeList); + await this.preferences.put("lastTimeMs", this.lastTimeMs); + this.flush(); } } @@ -186,13 +186,13 @@ export class TimerController { * Notification of status change */ private async notifyStateChanges() { - LogUtil.info(`${TAG} state update ${this.state}`) + LogUtil.info(`${TAG} state update ${this.state}`); if (this.stateUpdateListener) { - this.stateUpdateListener(this.state) + this.stateUpdateListener(this.state); } if (this.preferences) { - await this.preferences.put("state", this.state) - this.flush() + await this.preferences.put("state", this.state); + this.flush(); } } @@ -214,7 +214,7 @@ export class TimerController { * @param listener */ public setStateUpdateListener(listener: (TimerState) => void) { - LogUtil.info(`${TAG} setStateUpdateListener`) + LogUtil.info(`${TAG} setStateUpdateListener`); this.stateUpdateListener = listener; } @@ -223,7 +223,7 @@ export class TimerController { * @param listener */ public setTimeUpdateListener(listener: (currentTimeMs: number) => void) { - LogUtil.info(`${TAG} setTimeUpdateListener`) + LogUtil.info(`${TAG} setTimeUpdateListener`); this.timeUpdateListener = listener; } @@ -232,7 +232,7 @@ export class TimerController { * @param listener */ public setClockUpdateListener(listener: (currentTimeMs: number) => void) { - LogUtil.info(`${TAG} setClockUpdateListener`) + LogUtil.info(`${TAG} setClockUpdateListener`); this.clockUpdateListener = listener; } @@ -241,7 +241,7 @@ export class TimerController { * @param listener */ public setTimeListUpdateListener(listener: (timeList: Array, lastTimeMs: number) => void) { - LogUtil.info(`${TAG} setTimeListUpdateListener`) + LogUtil.info(`${TAG} setTimeListUpdateListener`); this.timeListUpdateListener = listener; } } \ No newline at end of file diff --git a/product/pc/src/main/ets/Application/MyAbilityStage.ts b/product/pc/src/main/ets/Application/MyAbilityStage.ts index bf6bcb9..b3f3c30 100644 --- a/product/pc/src/main/ets/Application/MyAbilityStage.ts +++ b/product/pc/src/main/ets/Application/MyAbilityStage.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import AbilityStage from "@ohos.application.AbilityStage" export default class MyAbilityStage extends AbilityStage { diff --git a/product/pc/src/main/ets/MainAbility/MainAbility.ts b/product/pc/src/main/ets/MainAbility/MainAbility.ts index 3b41402..5b86040 100644 --- a/product/pc/src/main/ets/MainAbility/MainAbility.ts +++ b/product/pc/src/main/ets/MainAbility/MainAbility.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import Ability from '@ohos.application.Ability' export default class MainAbility extends Ability { diff --git a/product/pc/src/main/ets/pages/Countdown.ets b/product/pc/src/main/ets/pages/Countdown.ets index 479fe1e..a88bc98 100644 --- a/product/pc/src/main/ets/pages/Countdown.ets +++ b/product/pc/src/main/ets/pages/Countdown.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,19 +13,26 @@ * limitations under the License. */ -import { CountdownView, CountdownController, CountdownState, TimeSelectView } from '@ohos/countdown' -import { ImageComponent, ConfigData } from '@ohos/common' +import { CountdownView, CountdownController, CountdownState, TimeSelectView } from '@ohos/countdown'; +import { ImageComponent, ConfigData } from '@ohos/common'; @Component export struct CountDown { - private headName: ResourceStr = $r("app.string.timer_clock") + private headName: ResourceStr = $r("app.string.timer_clock"); + private controller: CountdownController = new CountdownController(); + private viewSize: number = 232; + private originRadius: number = 5; + private scaleWidth: number = 2; + private scaleHeight: number = 10; + private scalePadding: number = 5; + private sca: number = 0.6; + private imgLength: number = 12; @State totalTime: number = 0; @State currentTime: number = 0; @State state: CountdownState = CountdownState.IDLE; - private controller: CountdownController = new CountdownController(); - @State hour: string = "00"; - @State minute: string = "00"; - @State second: string = "00"; + @State hour: string = '00'; + @State minute: string = '00'; + @State second: string = '00'; build() { Row() { @@ -33,38 +40,38 @@ export struct CountDown { Row() { Text(this.headName) .fontSize($r("app.float.font_30")) - .fontWeight(500) + .fontWeight(FontWeight.Regular) .fontColor($r("app.color.text_color")) - .lineHeight($r("app.float.wh_value_21")) + .lineHeight($r("app.float.wh_value_21")); }.width(ConfigData.WH_100_100) .padding({ left: $r("app.float.wh_value_24") }) - .height($r("app.float.wh_value_28")) + .height($r("app.float.wh_value_28")); Column() { CountdownView({ - viewSize: 232, + viewSize: this.viewSize, totalTime: this.totalTime, currentTime: this.currentTime, state: this.state, - originRadius: 5, - scaleWidth: 2, - scaleHeight: 10, - scalePadding: 5 - }) - }.margin({ top: $r("app.float.wh_value_38"), bottom: $r("app.float.wh_value_38") }) + originRadius: this.originRadius, + scaleWidth: this.scaleWidth, + scaleHeight: this.scaleHeight, + scalePadding: this.scalePadding + }); + }.margin({ top: $r("app.float.wh_value_38"), bottom: $r("app.float.wh_value_38") }); Column() { - Text(this.hour + ":" + this.minute + ":" + this.second) + Text(this.hour + ':' + this.minute + ':' + this.second) .lineHeight($r("app.float.wh_value_16")) .fontColor($r("app.color.text_color")) - .fontWeight(500) - .fontSize($r("app.float.font_20")) - }.width(ConfigData.WH_100_100) + .fontWeight(FontWeight.Regular) + .fontSize($r("app.float.font_20")); + }.width(ConfigData.WH_100_100); } .height(ConfigData.WH_100_100) - .width($r("app.float.wh_value_304")) + .width($r("app.float.wh_value_304")); - Divider().vertical(true).width($r("app.float.wh_value_0_5")) + Divider().vertical(true).width($r("app.float.wh_value_0_5")); Column() { Column() { TimeSelectView({ @@ -73,68 +80,68 @@ export struct CountDown { hour: $hour, minute: $minute, second: $second, - sca: 0.6, + sca: this.sca, callBack: this.timeSelectCallBack - }) + }); } .justifyContent(FlexAlign.Center) .visibility((this.state == CountdownState.IDLE || this.state == CountdownState.PREPARED) ? Visibility.Visible : Visibility.Hidden) .padding($r("app.float.distance_12")) .height($r("app.float.wh_value_324")) - .flexShrink(1) + .flexShrink(1); Row() { Row() { ImageComponent({ color: $r("app.color.white"), imageSrc: $r("app.media.ic_clock_refresh"), - imgLength: 12 - }) + imgLength: this.imgLength + }); } .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { - this.controller.reset() - }) + this.controller.reset(); + }); Row() { ImageComponent({ color: $r("app.color.selected_text_color"), imageSrc: this.state == CountdownState.RUNNING ? $r('app.media.ic_clock_suspend') : $r('app.media.ic_clock_play'), - imgLength: 12 - }) + imgLength: this.imgLength + }); } .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { if (this.state == CountdownState.PREPARED) { - this.controller.setTime(this.totalTime) - this.controller.start() + this.controller.setTime(this.totalTime); + this.controller.start(); } else if (this.state == CountdownState.PAUSED) { - this.controller.start() + this.controller.start(); } else if (this.state == CountdownState.RUNNING) { - this.controller.pause() + this.controller.pause(); } - }) + }); Row() { ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_sound'), - imgLength: 12 - }) + imgLength: this.imgLength + }); } .onClick(() => { - }) + }); } .height($r("app.float.wh_value_24")) .width(ConfigData.WH_100_100) .justifyContent(FlexAlign.SpaceBetween) .margin({ bottom: $r("app.float.distance_10"), top: $r("app.float.distance_4") }) - .padding({ left: $r("app.float.distance_84"), right: $r("app.float.distance_84") }) + .padding({ left: $r("app.float.distance_84"), right: $r("app.float.distance_84") }); } .height(ConfigData.WH_100_100) - .width($r("app.float.wh_value_275_5")) + .width($r("app.float.wh_value_275_5")); } } @@ -142,29 +149,29 @@ export struct CountDown { * CallBack for TimeSelectView. */ private timeSelectCallBack: () => void = () => { - this.totalTime = (parseInt(this.hour) * 3600 + parseInt(this.minute) * 60 + parseInt(this.second)) * 1000 + this.totalTime = (parseInt(this.hour) * 60 * 60 + parseInt(this.minute) * 60 + parseInt(this.second)) * 1000; - this.controller.setTime(this.totalTime) + this.controller.setTime(this.totalTime); } aboutToAppear() { this.controller.setStateUpdateListener((state) => { - this.state = state + this.state = state; if (state == CountdownState.STOPPED) { - let date = new Date(this.totalTime) - this.hour = this.fill(date.getHours()) - this.minute = this.fill(date.getMinutes()) - this.second = this.fill(date.getSeconds()) - this.controller.reStart() + let date = new Date(this.totalTime); + this.hour = this.fill(date.getHours()); + this.minute = this.fill(date.getMinutes()); + this.second = this.fill(date.getSeconds()); + this.controller.reStart(); } }) this.controller.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { - this.currentTime = currentTimeMs - this.totalTime = totalTimeMs - let date = new Date(this.currentTime) - this.hour = this.fill(date.getHours()) - this.minute = this.fill(date.getMinutes()) - this.second = this.fill(date.getSeconds()) + this.currentTime = currentTimeMs; + this.totalTime = totalTimeMs; + let date = new Date(this.currentTime); + this.hour = this.fill(date.getHours()); + this.minute = this.fill(date.getMinutes()); + this.second = this.fill(date.getSeconds()); }) this.controller.getData(); } @@ -173,6 +180,6 @@ export struct CountDown { * Make up 0 if less than 10. */ fill(value) { - return (value > 9 ? "" : "0") + value; + return (value > 9 ? '' : '0') + value; } } \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/index.ets b/product/pc/src/main/ets/pages/index.ets index d23cced..0cbb3b9 100644 --- a/product/pc/src/main/ets/pages/index.ets +++ b/product/pc/src/main/ets/pages/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { ConfigData } from '@ohos/common' import { Timer } from './timer/Timer' import { CountDown } from './Countdown' diff --git a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets index 9626f99..8f6a210 100644 --- a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerController } from "@ohos/timer" import { TimerUtil, ConfigData } from '@ohos/common' diff --git a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets index 3afb844..3b559ee 100644 --- a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerUtil, ConfigData } from '@ohos/common' @Component diff --git a/product/pc/src/main/ets/pages/timer/Timer.ets b/product/pc/src/main/ets/pages/timer/Timer.ets index 0bea8e1..abed22f 100644 --- a/product/pc/src/main/ets/pages/timer/Timer.ets +++ b/product/pc/src/main/ets/pages/timer/Timer.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerController } from "@ohos/timer" import { ConfigData } from '@ohos/common' import { TimerClock } from './TimerClock' diff --git a/product/pc/src/main/ets/pages/timer/TimerClock.ets b/product/pc/src/main/ets/pages/timer/TimerClock.ets index 47e1a8c..80ae5eb 100644 --- a/product/pc/src/main/ets/pages/timer/TimerClock.ets +++ b/product/pc/src/main/ets/pages/timer/TimerClock.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerView, TimerController } from "@ohos/timer" const CLOCK_SIZE = 232 diff --git a/product/pc/src/main/ets/pages/timer/TimerControl.ets b/product/pc/src/main/ets/pages/timer/TimerControl.ets index 8a028e0..8cfc2cb 100644 --- a/product/pc/src/main/ets/pages/timer/TimerControl.ets +++ b/product/pc/src/main/ets/pages/timer/TimerControl.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerController, TimerState } from "@ohos/timer" import { ImageComponent, ConfigData } from '@ohos/common' diff --git a/product/phone/src/main/ets/Application/MyAbilityStage.ts b/product/phone/src/main/ets/Application/MyAbilityStage.ts index bf6bcb9..b3f3c30 100644 --- a/product/phone/src/main/ets/Application/MyAbilityStage.ts +++ b/product/phone/src/main/ets/Application/MyAbilityStage.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import AbilityStage from "@ohos.application.AbilityStage" export default class MyAbilityStage extends AbilityStage { diff --git a/product/phone/src/main/ets/MainAbility/MainAbility.ts b/product/phone/src/main/ets/MainAbility/MainAbility.ts index 3b41402..5b86040 100644 --- a/product/phone/src/main/ets/MainAbility/MainAbility.ts +++ b/product/phone/src/main/ets/MainAbility/MainAbility.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import Ability from '@ohos.application.Ability' export default class MainAbility extends Ability { diff --git a/product/phone/src/main/ets/pages/Countdown.ets b/product/phone/src/main/ets/pages/Countdown.ets index efa0338..e71eaf5 100644 --- a/product/phone/src/main/ets/pages/Countdown.ets +++ b/product/phone/src/main/ets/pages/Countdown.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,19 +13,20 @@ * limitations under the License. */ -import { CountdownView, CountdownController, CountdownState, TimeSelectView } from '@ohos/countdown' -import { ImageComponent, ConfigData } from '@ohos/common' +import { CountdownView, CountdownController, CountdownState, TimeSelectView } from '@ohos/countdown'; +import { ImageComponent, ConfigData } from '@ohos/common'; @Component export struct CountDown { - private headName: ResourceStr = $r("app.string.timer_clock") + private headName: ResourceStr = $r("app.string.timer_clock"); + private controller: CountdownController = new CountdownController(); + private viewSize: number = 373.5; @State totalTime: number = 0; @State currentTime: number = 0; @State state: CountdownState = CountdownState.IDLE; - private controller: CountdownController = new CountdownController(); - @State hour: string = "00"; - @State minute: string = "00"; - @State second: string = "00"; + @State hour: string = '00'; + @State minute: string = '00'; + @State second: string = '00'; build() { Column() { @@ -34,30 +35,30 @@ export struct CountDown { .fontSize($r("app.float.font_48")) .fontColor($r("app.color.text_color")) .lineHeight($r("app.float.wh_value_44")) - .fontWeight(500) + .fontWeight(FontWeight.Regular) .textOverflow({ overflow: TextOverflow.Ellipsis }) .textAlign(TextAlign.Center) - .margin({ top: $r("app.float.distance_18_5"), bottom: $r("app.float.distance_12") }) + .margin({ top: $r("app.float.distance_18_5"), bottom: $r("app.float.distance_12") }); } - .width(ConfigData.WH_100_100) + .width(ConfigData.WH_100_100); Scroll() { Column() { Column() { CountdownView({ - viewSize: 373.5, + viewSize: this.viewSize, totalTime: this.totalTime, currentTime: this.currentTime, state: this.state - }) + }); } - .margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_16") }) + .margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_16") }); - Text(this.hour + ":" + this.minute + ":" + this.second) + Text(this.hour + ':' + this.minute + ':' + this.second) .fontSize($r("app.float.font_40")) .fontColor($r("app.color.text_color")) .lineHeight($r("app.float.wh_value_32")) - .fontWeight(500) + .fontWeight(FontWeight.Regular); Column() { TimeSelectView({ @@ -65,85 +66,85 @@ export struct CountDown { minute: $minute, second: $second, callBack: this.timeSelectCallBack - }) + }); } .margin({ top: $r("app.float.distance_42"), bottom: $r("app.float.distance_24") }) - .visibility((this.state == CountdownState.IDLE || this.state == CountdownState.PREPARED) ? Visibility.Visible : Visibility.None) + .visibility((this.state == CountdownState.IDLE || this.state == CountdownState.PREPARED) ? Visibility.Visible : Visibility.None); } } .height($r("app.float.wh_value_516")) .width(ConfigData.WH_100_100) - .scrollBar(BarState.Off) + .scrollBar(BarState.Off); Row() { Row() { - ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_refresh') }) + ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_refresh') }); } .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { - this.controller.reset() - }) + this.controller.reset(); + }); Row() { ImageComponent({ color: $r("app.color.selected_text_color"), imageSrc: this.state == CountdownState.RUNNING ? $r('app.media.ic_clock_suspend') : $r('app.media.ic_clock_play') - }) + }); } .margin({ left: $r("app.float.distance_48"), right: $r("app.float.distance_48") }) .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { if (this.state == CountdownState.PREPARED) { - this.controller.setTime(this.totalTime) - this.controller.start() + this.controller.setTime(this.totalTime); + this.controller.start(); } else if (this.state == CountdownState.PAUSED) { - this.controller.start() + this.controller.start(); } else if (this.state == CountdownState.RUNNING) { - this.controller.pause() + this.controller.pause(); } }) Row() { - ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_sound') }) + ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_sound') }); } .onClick(() => { - }) - }.margin({ top: $r("app.float.distance_16"), bottom: $r("app.float.distance_16") }) + }); + }.margin({ top: $r("app.float.distance_16"), bottom: $r("app.float.distance_16") }); } .width(ConfigData.WH_100_100) .height(ConfigData.WH_100_100) - .padding({ left: $r("app.float.distance_32"), right: $r("app.float.distance_32") }) + .padding({ left: $r("app.float.distance_32"), right: $r("app.float.distance_32") }); } /** * CallBack for TimeSelectView. */ private timeSelectCallBack: () => void = () => { - this.totalTime = (parseInt(this.hour) * 3600 + parseInt(this.minute) * 60 + parseInt(this.second)) * 1000 + this.totalTime = (parseInt(this.hour) * 60 * 60 + parseInt(this.minute) * 60 + parseInt(this.second)) * 1000; - this.controller.setTime(this.totalTime) + this.controller.setTime(this.totalTime); } aboutToAppear() { this.controller.setStateUpdateListener((state) => { - this.state = state + this.state = state; if (state == CountdownState.STOPPED) { - let date = new Date(this.totalTime) - this.hour = this.fill(date.getHours()) - this.minute = this.fill(date.getMinutes()) - this.second = this.fill(date.getSeconds()) - this.controller.reStart() + let date = new Date(this.totalTime); + this.hour = this.fill(date.getHours()); + this.minute = this.fill(date.getMinutes()); + this.second = this.fill(date.getSeconds()); + this.controller.reStart(); } }) this.controller.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { - this.currentTime = currentTimeMs - this.totalTime = totalTimeMs - let date = new Date(this.currentTime) - this.hour = this.fill(date.getHours()) - this.minute = this.fill(date.getMinutes()) - this.second = this.fill(date.getSeconds()) + this.currentTime = currentTimeMs; + this.totalTime = totalTimeMs; + let date = new Date(this.currentTime); + this.hour = this.fill(date.getHours()); + this.minute = this.fill(date.getMinutes()); + this.second = this.fill(date.getSeconds()); }) this.controller.getData(); } @@ -152,6 +153,6 @@ export struct CountDown { * Make up 0 if less than 10. */ fill(value) { - return (value > 9 ? "" : "0") + value; + return (value > 9 ? '' : '0') + value; } } \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/index.ets b/product/phone/src/main/ets/pages/index.ets index ce4de7b..61a75e9 100644 --- a/product/phone/src/main/ets/pages/index.ets +++ b/product/phone/src/main/ets/pages/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { ConfigData } from '@ohos/common' import { Timer } from './timer/Timer' import { CountDown } from './Countdown' diff --git a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets index ca62137..6093866 100644 --- a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerController } from "@ohos/timer" import { TimerUtil, ConfigData } from '@ohos/common' diff --git a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets index 1652930..8edf9a8 100644 --- a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerUtil, ConfigData } from '@ohos/common' @Component diff --git a/product/phone/src/main/ets/pages/timer/Timer.ets b/product/phone/src/main/ets/pages/timer/Timer.ets index fade5ec..bb4d4ae 100644 --- a/product/phone/src/main/ets/pages/timer/Timer.ets +++ b/product/phone/src/main/ets/pages/timer/Timer.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerController } from "@ohos/timer" import { ConfigData } from '@ohos/common' import { TimerClock } from './TimerClock' diff --git a/product/phone/src/main/ets/pages/timer/TimerClock.ets b/product/phone/src/main/ets/pages/timer/TimerClock.ets index c39f485..410b1dc 100644 --- a/product/phone/src/main/ets/pages/timer/TimerClock.ets +++ b/product/phone/src/main/ets/pages/timer/TimerClock.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerView, TimerController } from "@ohos/timer" const CLOCK_SIZE = 373.5 diff --git a/product/phone/src/main/ets/pages/timer/TimerControl.ets b/product/phone/src/main/ets/pages/timer/TimerControl.ets index 8c8558f..e5e64c6 100644 --- a/product/phone/src/main/ets/pages/timer/TimerControl.ets +++ b/product/phone/src/main/ets/pages/timer/TimerControl.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { TimerController, TimerState } from "@ohos/timer" import { ImageComponent, ConfigData } from '@ohos/common' -- Gitee From 2bb0cabb24a0ac0a2fd2ef1acadac558a4299322 Mon Sep 17 00:00:00 2001 From: liu_gang Date: Fri, 11 Nov 2022 09:38:18 +0800 Subject: [PATCH 03/19] Change the Util method to static Signed-off-by: liu_gang --- common/src/main/ets/utils/LogUtil.ts | 19 +++++++------------ common/src/main/ets/utils/TimerUtil.ets | 12 ++++-------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/common/src/main/ets/utils/LogUtil.ts b/common/src/main/ets/utils/LogUtil.ts index a6494c4..654bd01 100644 --- a/common/src/main/ets/utils/LogUtil.ts +++ b/common/src/main/ets/utils/LogUtil.ts @@ -21,29 +21,24 @@ const TAG = "[Clock]"; /** * log package tool class */ -export class LogUtil { - debug(msg): void { +export default class LogUtil { + static debug(msg): void { HiLog.debug(DOMAIN, TAG, msg); } - log(msg): void { + static log(msg): void { HiLog.info(DOMAIN, TAG, msg); } - info(msg): void { + static info(msg): void { HiLog.info(DOMAIN, TAG, msg); } - warn(msg): void { + static warn(msg): void { HiLog.warn(DOMAIN, TAG, msg); } - error(msg): void { + static error(msg): void { HiLog.error(DOMAIN, TAG, msg); } -} - -let mLogUtil = new LogUtil(); - -export default mLogUtil as LogUtil -; \ No newline at end of file +} \ No newline at end of file diff --git a/common/src/main/ets/utils/TimerUtil.ets b/common/src/main/ets/utils/TimerUtil.ets index d97fe7c..2495a1c 100644 --- a/common/src/main/ets/utils/TimerUtil.ets +++ b/common/src/main/ets/utils/TimerUtil.ets @@ -15,13 +15,13 @@ import ConfigData from "./ConfigData"; -export class TimerUtil { +export default class TimerUtil { /** * Time format conversion * * @param timestamp */ - timeFormat(timestamp: number) { + static timeFormat(timestamp: number) { if (timestamp <= 0) { return "00:00.00"; } @@ -48,11 +48,7 @@ export class TimerUtil { * * @param num */ - addZero(num) { + static addZero(num) { return (num < 10 ? "0" + num : num).toString(); } -} - -let mTimerUtil = new TimerUtil(); - -export default mTimerUtil as TimerUtil; \ No newline at end of file +} \ No newline at end of file -- Gitee From 7d2bcac302f707d2a7a0abbe133728175fd972b4 Mon Sep 17 00:00:00 2001 From: liu_gang Date: Mon, 14 Nov 2022 14:50:48 +0800 Subject: [PATCH 04/19] add semicolons Signed-off-by: liu_gang --- .../src/main/ets/components/CountdownView.ets | 6 ++--- .../src/main/ets/components/TimerView.ets | 6 ++--- .../main/ets/controller/TimerController.ets | 2 ++ product/pc/src/main/ets/pages/index.ets | 12 +++++----- .../ets/pages/timer/CurrentTimeDisplay.ets | 12 +++++----- .../src/main/ets/pages/timer/TimeOfRecord.ets | 6 ++--- product/pc/src/main/ets/pages/timer/Timer.ets | 24 +++++++++---------- .../src/main/ets/pages/timer/TimerClock.ets | 10 ++++---- .../src/main/ets/pages/timer/TimerControl.ets | 22 ++++++++--------- product/phone/src/main/ets/pages/index.ets | 12 +++++----- .../ets/pages/timer/CurrentTimeDisplay.ets | 12 +++++----- .../src/main/ets/pages/timer/TimeOfRecord.ets | 6 ++--- .../phone/src/main/ets/pages/timer/Timer.ets | 24 +++++++++---------- .../src/main/ets/pages/timer/TimerClock.ets | 10 ++++---- .../src/main/ets/pages/timer/TimerControl.ets | 22 ++++++++--------- 15 files changed, 94 insertions(+), 92 deletions(-) diff --git a/feature/countdown/src/main/ets/components/CountdownView.ets b/feature/countdown/src/main/ets/components/CountdownView.ets index 619de09..280587d 100644 --- a/feature/countdown/src/main/ets/components/CountdownView.ets +++ b/feature/countdown/src/main/ets/components/CountdownView.ets @@ -13,8 +13,8 @@ * limitations under the License. */ -import { CountdownState } from '../controller/CountdownController' -import { ConfigData } from '@ohos/common' +import { CountdownState } from '../controller/CountdownController'; +import { ConfigData } from '@ohos/common'; @Component export struct CountdownView { @@ -108,7 +108,7 @@ export struct CountdownView { .border({ radius: this.viewSize }) .shadow({ radius: $r("app.float.radius_value_26_5"), color: this.shadowColor }) .onReady(() => { - this.draw() + this.draw(); }); } } \ No newline at end of file diff --git a/feature/timer/src/main/ets/components/TimerView.ets b/feature/timer/src/main/ets/components/TimerView.ets index 6ff76fe..2355e6d 100644 --- a/feature/timer/src/main/ets/components/TimerView.ets +++ b/feature/timer/src/main/ets/components/TimerView.ets @@ -49,7 +49,7 @@ export struct TimerView { .height(this.sSize) .aspectRatio(1.0) .onReady(() => { - this.drawDials() + this.drawDials(); }) .backgroundColor($r("app.color.background_color_white")) .borderRadius(this.sSize / 2) @@ -58,13 +58,13 @@ export struct TimerView { .height(this.sSize) .aspectRatio(1.0) .onReady(() => { - this.drawMinutes(this.currentTime % (60 * 60 * 1000) / (60 * 1000)) + this.drawMinutes(this.currentTime % (60 * 60 * 1000) / (60 * 1000)); }); Canvas(this.secondContext) .height(this.sSize) .aspectRatio(1.0) .onReady(() => { - this.drawSecond(this.currentTime % (60 * 1000) / 1000) + this.drawSecond(this.currentTime % (60 * 1000) / 1000); }); } } diff --git a/feature/timer/src/main/ets/controller/TimerController.ets b/feature/timer/src/main/ets/controller/TimerController.ets index 41e9099..56ce224 100644 --- a/feature/timer/src/main/ets/controller/TimerController.ets +++ b/feature/timer/src/main/ets/controller/TimerController.ets @@ -120,6 +120,7 @@ export class TimerController { if (timeList == 0) { this.timeList = []; } else { + //@ts-ignore this.timeList = > timeList; } @@ -176,6 +177,7 @@ export class TimerController { this.timeListUpdateListener(this.timeList, this.lastTimeMs); } if (this.preferences) { + //@ts-ignore await this.preferences.put("timeList", this.timeList); await this.preferences.put("lastTimeMs", this.lastTimeMs); this.flush(); diff --git a/product/pc/src/main/ets/pages/index.ets b/product/pc/src/main/ets/pages/index.ets index 0cbb3b9..f2f63f3 100644 --- a/product/pc/src/main/ets/pages/index.ets +++ b/product/pc/src/main/ets/pages/index.ets @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ConfigData } from '@ohos/common' -import { Timer } from './timer/Timer' -import { CountDown } from './Countdown' +import { ConfigData } from '@ohos/common'; +import { Timer } from './timer/Timer'; +import { CountDown } from './Countdown'; @Entry @Component @@ -36,8 +36,8 @@ struct Index { icon: $r("app.media.ic_clock_second_chronograph"), selectedIcon: $r("app.media.ic_clock_second_chronograph_click") }, - ] - @State featureIndex: number = 1 + ]; + @State featureIndex: number = 1; build() { Row() { @@ -55,7 +55,7 @@ struct Index { .margin({ top: $r("app.float.distance_1") }) } .onClick(() => { - this.featureIndex = item.i + this.featureIndex = item.i; }) }, item => item.i) diff --git a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets index 8f6a210..af9368f 100644 --- a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -13,18 +13,18 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer" -import { TimerUtil, ConfigData } from '@ohos/common' +import { TimerController } from "@ohos/timer"; +import { TimerUtil, ConfigData } from '@ohos/common'; @Component export struct CurrentTimeDisplay { - @State currentTime: number = 0 - @Prop lastTimeMs: number - @State timerController: TimerController = new TimerController() + @State currentTime: number = 0; + @Prop lastTimeMs: number; + @State timerController: TimerController = new TimerController(); aboutToAppear() { this.timerController.setTimeUpdateListener((currentTimeMs: number) => { - this.currentTime = currentTimeMs + this.currentTime = currentTimeMs; }) } diff --git a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets index 3b559ee..5a234a6 100644 --- a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets @@ -13,12 +13,12 @@ * limitations under the License. */ -import { TimerUtil, ConfigData } from '@ohos/common' +import { TimerUtil, ConfigData } from '@ohos/common'; @Component export struct TimeOfRecord { - @State timeList: Array = [] - @Prop lastTimeMs: number + @State timeList: Array = []; + @Prop lastTimeMs: number; build() { Column() { diff --git a/product/pc/src/main/ets/pages/timer/Timer.ets b/product/pc/src/main/ets/pages/timer/Timer.ets index abed22f..58ca103 100644 --- a/product/pc/src/main/ets/pages/timer/Timer.ets +++ b/product/pc/src/main/ets/pages/timer/Timer.ets @@ -13,26 +13,26 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer" -import { ConfigData } from '@ohos/common' -import { TimerClock } from './TimerClock' -import { CurrentTimeDisplay } from './CurrentTimeDisplay' -import { TimeOfRecord } from './TimeOfRecord' -import { TimerControl } from './TimerControl' +import { TimerController } from "@ohos/timer"; +import { ConfigData } from '@ohos/common'; +import { TimerClock } from './TimerClock'; +import { CurrentTimeDisplay } from './CurrentTimeDisplay'; +import { TimeOfRecord } from './TimeOfRecord'; +import { TimerControl } from './TimerControl'; @Component export struct Timer { - timerController: TimerController = new TimerController() - private timeList: Array = [] - @State lastTimeMs: number = 0 + timerController: TimerController = new TimerController(); + private timeList: Array = []; + @State lastTimeMs: number = 0; aboutToAppear() { this.timerController.setTimeListUpdateListener((timeList: Array, lastTimeMs: number) => { - this.timeList = timeList - this.lastTimeMs = lastTimeMs + this.timeList = timeList; + this.lastTimeMs = lastTimeMs; }) setTimeout(() => { - this.timerController.reload() + this.timerController.reload(); }, 100) } diff --git a/product/pc/src/main/ets/pages/timer/TimerClock.ets b/product/pc/src/main/ets/pages/timer/TimerClock.ets index 80ae5eb..6845169 100644 --- a/product/pc/src/main/ets/pages/timer/TimerClock.ets +++ b/product/pc/src/main/ets/pages/timer/TimerClock.ets @@ -13,18 +13,18 @@ * limitations under the License. */ -import { TimerView, TimerController } from "@ohos/timer" +import { TimerView, TimerController } from "@ohos/timer"; -const CLOCK_SIZE = 232 +const CLOCK_SIZE = 232; @Component export struct TimerClock { - @State currentTime: number = 0 - @State timerController: TimerController = new TimerController() + @State currentTime: number = 0; + @State timerController: TimerController = new TimerController(); aboutToAppear() { this.timerController.setClockUpdateListener((currentTimeMs: number) => { - this.currentTime = currentTimeMs + this.currentTime = currentTimeMs; }) } diff --git a/product/pc/src/main/ets/pages/timer/TimerControl.ets b/product/pc/src/main/ets/pages/timer/TimerControl.ets index 8cfc2cb..ae32529 100644 --- a/product/pc/src/main/ets/pages/timer/TimerControl.ets +++ b/product/pc/src/main/ets/pages/timer/TimerControl.ets @@ -13,20 +13,20 @@ * limitations under the License. */ -import { TimerController, TimerState } from "@ohos/timer" -import { ImageComponent, ConfigData } from '@ohos/common' +import { TimerController, TimerState } from "@ohos/timer"; +import { ImageComponent, ConfigData } from '@ohos/common'; -const DEFAULT_ICON_SIZE: number = 12 +const DEFAULT_ICON_SIZE: number = 12; @Component export struct TimerControl { - private timerController: TimerController = new TimerController() - @State state: TimerState = TimerState.IDLE - private timeList: Array = [] + private timerController: TimerController = new TimerController(); + @State state: TimerState = TimerState.IDLE; + private timeList: Array = []; aboutToAppear() { this.timerController.setStateUpdateListener((state) => { - this.state = state + this.state = state; }) } @@ -54,11 +54,11 @@ export struct TimerControl { }) }.onClick(() => { if (this.state == TimerState.IDLE) { - this.timerController.start() + this.timerController.start(); } else if (this.state == TimerState.RUNNING) { - this.timerController.pause() + this.timerController.pause(); } else if (this.state == TimerState.PAUSED) { - this.timerController.start() + this.timerController.start(); } }) @@ -72,7 +72,7 @@ export struct TimerControl { .opacity(this.state == TimerState.RUNNING ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) .enabled(this.state == TimerState.RUNNING) .onClick(() => { - this.timerController.writeTime() + this.timerController.writeTime(); }) } .height($r("app.float.wh_value_24")) diff --git a/product/phone/src/main/ets/pages/index.ets b/product/phone/src/main/ets/pages/index.ets index 61a75e9..52bcdc1 100644 --- a/product/phone/src/main/ets/pages/index.ets +++ b/product/phone/src/main/ets/pages/index.ets @@ -13,9 +13,9 @@ * limitations under the License. */ -import { ConfigData } from '@ohos/common' -import { Timer } from './timer/Timer' -import { CountDown } from './Countdown' +import { ConfigData } from '@ohos/common'; +import { Timer } from './timer/Timer'; +import { CountDown } from './Countdown'; @Entry @Component @@ -36,8 +36,8 @@ struct Index { icon: $r("app.media.ic_clock_second_chronograph"), selectedIcon: $r("app.media.ic_clock_second_chronograph_click") }, - ] - @State featureIndex: number = 1 + ]; + @State featureIndex: number = 1; build() { Column() { @@ -68,7 +68,7 @@ struct Index { .margin({ top: $r("app.float.distance_3") }) }.width(ConfigData.WH_33_100) .onClick(() => { - this.featureIndex = item.i + this.featureIndex = item.i; }) }, item => item.i) } diff --git a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets index 6093866..8409051 100644 --- a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -13,18 +13,18 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer" -import { TimerUtil, ConfigData } from '@ohos/common' +import { TimerController } from "@ohos/timer"; +import { TimerUtil, ConfigData } from '@ohos/common'; @Component export struct CurrentTimeDisplay { - @State currentTime: number = 0 - @Prop lastTimeMs: number - @State timerController: TimerController = new TimerController() + @State currentTime: number = 0; + @Prop lastTimeMs: number; + @State timerController: TimerController = new TimerController(); aboutToAppear() { this.timerController.setTimeUpdateListener((currentTimeMs: number) => { - this.currentTime = currentTimeMs + this.currentTime = currentTimeMs; }) } diff --git a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets index 8edf9a8..3a4c397 100644 --- a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets @@ -13,12 +13,12 @@ * limitations under the License. */ -import { TimerUtil, ConfigData } from '@ohos/common' +import { TimerUtil, ConfigData } from '@ohos/common'; @Component export struct TimeOfRecord { - @State timeList: Array = [] - @Prop lastTimeMs: number + @State timeList: Array = []; + @Prop lastTimeMs: number; build() { Column() { diff --git a/product/phone/src/main/ets/pages/timer/Timer.ets b/product/phone/src/main/ets/pages/timer/Timer.ets index bb4d4ae..849be19 100644 --- a/product/phone/src/main/ets/pages/timer/Timer.ets +++ b/product/phone/src/main/ets/pages/timer/Timer.ets @@ -13,26 +13,26 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer" -import { ConfigData } from '@ohos/common' -import { TimerClock } from './TimerClock' -import { CurrentTimeDisplay } from './CurrentTimeDisplay' -import { TimeOfRecord } from './TimeOfRecord' -import { TimerControl } from './TimerControl' +import { TimerController } from "@ohos/timer"; +import { ConfigData } from '@ohos/common'; +import { TimerClock } from './TimerClock'; +import { CurrentTimeDisplay } from './CurrentTimeDisplay'; +import { TimeOfRecord } from './TimeOfRecord'; +import { TimerControl } from './TimerControl'; @Component export struct Timer { - private timerController: TimerController = new TimerController() - private timeList: Array = [] - @State lastTimeMs: number = 0 + private timerController: TimerController = new TimerController(); + private timeList: Array = []; + @State lastTimeMs: number = 0; aboutToAppear() { this.timerController.setTimeListUpdateListener((timeList: Array, lastTimeMs: number) => { - this.timeList = timeList - this.lastTimeMs = lastTimeMs + this.timeList = timeList; + this.lastTimeMs = lastTimeMs; }) setTimeout(() => { - this.timerController.reload() + this.timerController.reload(); }, 100) } diff --git a/product/phone/src/main/ets/pages/timer/TimerClock.ets b/product/phone/src/main/ets/pages/timer/TimerClock.ets index 410b1dc..d241177 100644 --- a/product/phone/src/main/ets/pages/timer/TimerClock.ets +++ b/product/phone/src/main/ets/pages/timer/TimerClock.ets @@ -13,18 +13,18 @@ * limitations under the License. */ -import { TimerView, TimerController } from "@ohos/timer" +import { TimerView, TimerController } from "@ohos/timer"; -const CLOCK_SIZE = 373.5 +const CLOCK_SIZE = 373.5; @Component export struct TimerClock { - @State currentTime: number = 0 - @State timerController: TimerController = new TimerController() + @State currentTime: number = 0; + @State timerController: TimerController = new TimerController(); aboutToAppear() { this.timerController.setClockUpdateListener((currentTimeMs: number) => { - this.currentTime = currentTimeMs + this.currentTime = currentTimeMs; }) } diff --git a/product/phone/src/main/ets/pages/timer/TimerControl.ets b/product/phone/src/main/ets/pages/timer/TimerControl.ets index e5e64c6..adbd0b1 100644 --- a/product/phone/src/main/ets/pages/timer/TimerControl.ets +++ b/product/phone/src/main/ets/pages/timer/TimerControl.ets @@ -13,18 +13,18 @@ * limitations under the License. */ -import { TimerController, TimerState } from "@ohos/timer" -import { ImageComponent, ConfigData } from '@ohos/common' +import { TimerController, TimerState } from "@ohos/timer"; +import { ImageComponent, ConfigData } from '@ohos/common'; @Component export struct TimerControl { - private timerController: TimerController = new TimerController() - @State state: TimerState = TimerState.IDLE - private timeList: Array = [] + private timerController: TimerController = new TimerController(); + @State state: TimerState = TimerState.IDLE; + private timeList: Array = []; aboutToAppear() { this.timerController.setStateUpdateListener((state) => { - this.state = state + this.state = state; }) } @@ -36,7 +36,7 @@ export struct TimerControl { .opacity(this.state == TimerState.PAUSED ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) .enabled(this.state == TimerState.PAUSED) .onClick(() => { - this.timerController.reset() + this.timerController.reset(); }) Row() { @@ -48,11 +48,11 @@ export struct TimerControl { }) }.onClick(() => { if (this.state == TimerState.IDLE) { - this.timerController.start() + this.timerController.start(); } else if (this.state == TimerState.RUNNING) { - this.timerController.pause() + this.timerController.pause(); } else if (this.state == TimerState.PAUSED) { - this.timerController.start() + this.timerController.start(); } }) @@ -62,7 +62,7 @@ export struct TimerControl { .opacity(this.state == TimerState.RUNNING ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) .enabled(this.state == TimerState.RUNNING) .onClick(() => { - this.timerController.writeTime() + this.timerController.writeTime(); }) } .height($r("app.float.wh_value_64")) -- Gitee From 61646f02fa2e0eaf22e95765f348b1bb9331f00a Mon Sep 17 00:00:00 2001 From: liu_gang Date: Mon, 14 Nov 2022 14:55:29 +0800 Subject: [PATCH 05/19] change single quotes and change string constant Signed-off-by: liu_gang --- common/src/main/ets/utils/LogUtil.ts | 4 +- common/src/main/ets/utils/TimerUtil.ets | 22 ++++---- .../src/main/ets/components/CountdownView.ets | 4 +- .../main/ets/components/TimeSelectView.ets | 34 ++++++------ .../src/main/ets/components/TimerView.ets | 12 ++--- .../main/ets/controller/TimerController.ets | 34 +++++++----- product/pc/src/main/ets/pages/Countdown.ets | 52 +++++++++---------- product/pc/src/main/ets/pages/index.ets | 36 ++++++------- .../ets/pages/timer/CurrentTimeDisplay.ets | 16 +++--- .../src/main/ets/pages/timer/TimeOfRecord.ets | 34 ++++++------ product/pc/src/main/ets/pages/timer/Timer.ets | 22 ++++---- .../src/main/ets/pages/timer/TimerClock.ets | 2 +- .../src/main/ets/pages/timer/TimerControl.ets | 28 +++++----- .../pc/src/ohosTest/ets/test/Ability.test.ets | 2 +- .../phone/src/main/ets/pages/Countdown.ets | 38 +++++++------- product/phone/src/main/ets/pages/index.ets | 32 ++++++------ .../ets/pages/timer/CurrentTimeDisplay.ets | 16 +++--- .../src/main/ets/pages/timer/TimeOfRecord.ets | 38 +++++++------- .../phone/src/main/ets/pages/timer/Timer.ets | 24 ++++----- .../src/main/ets/pages/timer/TimerClock.ets | 2 +- .../src/main/ets/pages/timer/TimerControl.ets | 24 ++++----- .../src/ohosTest/ets/test/Ability.test.ets | 2 +- 22 files changed, 242 insertions(+), 236 deletions(-) diff --git a/common/src/main/ets/utils/LogUtil.ts b/common/src/main/ets/utils/LogUtil.ts index 654bd01..831a269 100644 --- a/common/src/main/ets/utils/LogUtil.ts +++ b/common/src/main/ets/utils/LogUtil.ts @@ -13,10 +13,10 @@ * limitations under the License. */ -import HiLog from "@ohos.hilog"; +import HiLog from '@ohos.hilog'; const DOMAIN = 0x0500; -const TAG = "[Clock]"; +const TAG = '[Clock]'; /** * log package tool class diff --git a/common/src/main/ets/utils/TimerUtil.ets b/common/src/main/ets/utils/TimerUtil.ets index 2495a1c..5a24ee2 100644 --- a/common/src/main/ets/utils/TimerUtil.ets +++ b/common/src/main/ets/utils/TimerUtil.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import ConfigData from "./ConfigData"; +import ConfigData from './ConfigData'; export default class TimerUtil { /** @@ -21,34 +21,34 @@ export default class TimerUtil { * * @param timestamp */ - static timeFormat(timestamp: number) { + static timeFormat(timestamp: number): string { if (timestamp <= 0) { - return "00:00.00"; + return `00:00.00`; } - let timeStr = ""; + let timeStr = ``; let day = Math.floor(timestamp / ConfigData.ONE_DAY_TIME); if (day > 0) { - timeStr += this.addZero(day) + ":"; + timeStr += `${this.addZero(day)}:`; } let hour = Math.floor(timestamp % ConfigData.ONE_DAY_TIME / ConfigData.ONE_HOUR_TIME); if (hour > 0 || day > 0) { - timeStr += this.addZero(hour) + ":"; + timeStr += `${this.addZero(hour)}:`; } let min = Math.floor(timestamp % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME); - timeStr += this.addZero(min) + ":"; + timeStr += `${this.addZero(min)}:`; let sec = Math.floor(timestamp % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME); - timeStr += this.addZero(sec) + "."; + timeStr += `${this.addZero(sec)}.`; let mSec = Math.floor(timestamp % ConfigData.ONE_SECOND_TIME / 10); timeStr += this.addZero(mSec); return timeStr; } /** - * If the number is less than 10, add "0". + * If the number is less than 10, add '0". * * @param num */ - static addZero(num) { - return (num < 10 ? "0" + num : num).toString(); + static addZero(num): string { + return (num < 10 ? `0${num}` : num).toString(); } } \ No newline at end of file diff --git a/feature/countdown/src/main/ets/components/CountdownView.ets b/feature/countdown/src/main/ets/components/CountdownView.ets index 280587d..bb40a77 100644 --- a/feature/countdown/src/main/ets/components/CountdownView.ets +++ b/feature/countdown/src/main/ets/components/CountdownView.ets @@ -104,9 +104,9 @@ export struct CountdownView { Canvas(this.context) .width(this.viewSize) .height(this.viewSize) - .backgroundColor($r("app.color.background_color_white")) + .backgroundColor($r('app.color.background_color_white')) .border({ radius: this.viewSize }) - .shadow({ radius: $r("app.float.radius_value_26_5"), color: this.shadowColor }) + .shadow({ radius: $r('app.float.radius_value_26_5'), color: this.shadowColor }) .onReady(() => { this.draw(); }); diff --git a/feature/countdown/src/main/ets/components/TimeSelectView.ets b/feature/countdown/src/main/ets/components/TimeSelectView.ets index 3f33dcd..65075a3 100644 --- a/feature/countdown/src/main/ets/components/TimeSelectView.ets +++ b/feature/countdown/src/main/ets/components/TimeSelectView.ets @@ -19,8 +19,8 @@ const TAG = 'TimeSelectView : '; @Component export struct TimeSelectView { - private marginRight: number | Resource = $r("app.float.distance_30"); - private dividerMargin: number | Resource = $r("app.float.distance_75"); + private marginRight: number | Resource = $r('app.float.distance_30'); + private dividerMargin: number | Resource = $r('app.float.distance_75'); private hourRange: number[] = Array.from(new Array(ConfigData.HOUR_SELECT).keys()); private minuteRange: number[] = Array.from(new Array(ConfigData.MINUTE_SELECT).keys()); private secondRange: number[] = Array.from(new Array(ConfigData.SECOND_SELECT).keys()); @@ -36,7 +36,7 @@ export struct TimeSelectView { Row() { TimeSelectItem({ fruits: this.convert(this.hourRange), - text: $r("app.string.hour"), + text: $r('app.string.hour'), isVisibility: true, marginRight: this.marginRight, value: $hour, @@ -45,7 +45,7 @@ export struct TimeSelectView { TimeSelectItem({ fruits: this.convert(this.minuteRange), - text: $r("app.string.minute"), + text: $r('app.string.minute'), isVisibility: true, marginRight: this.marginRight, value: $minute, @@ -54,7 +54,7 @@ export struct TimeSelectView { TimeSelectItem({ fruits: this.convert(this.secondRange), - text: $r("app.string.second"), + text: $r('app.string.second'), isVisibility: false, marginRight: this.marginRight, value: $second, @@ -64,18 +64,18 @@ export struct TimeSelectView { Divider() .strokeWidth(1) - .color($r("app.color.divider_color")) + .color($r('app.color.divider_color')) .margin({ left: this.dividerMargin, - right: this.dividerMargin, top: $r("app.float.distance_35") + right: this.dividerMargin, top: $r('app.float.distance_35') }); Divider() .strokeWidth(1) - .color($r("app.color.divider_color")) + .color($r('app.color.divider_color')) .margin({ left: this.dividerMargin, - right: this.dividerMargin, bottom: $r("app.float.distance_78") + right: this.dividerMargin, bottom: $r('app.float.distance_78') }); } } @@ -99,9 +99,9 @@ struct TimeSelectItem { private fruits: string[] = []; private text: ResourceStr = ''; private isVisibility: boolean = true; - private marginRight: number | Resource = $r("app.float.distance_30"); - private componentWidth: number | Resource = $r("app.float.wh_value_40"); - private componentHeight: number | Resource = $r("app.float.wh_value_160"); + private marginRight: number | Resource = $r('app.float.distance_30'); + private componentWidth: number | Resource = $r('app.float.wh_value_40'); + private componentHeight: number | Resource = $r('app.float.wh_value_160'); private onChangCallBack?: () => void; @Link value: string; @@ -109,7 +109,7 @@ struct TimeSelectItem { Row() { Column() { TextPicker({ range: this.fruits, selected: Number(this.value) }) - .backgroundColor($r("app.color.background_color")) + .backgroundColor($r('app.color.background_color')) .width(this.componentWidth) .height(this.componentHeight) .onChange((value: string, index: number) => { @@ -117,12 +117,12 @@ struct TimeSelectItem { this.onChangCallBack(); LogUtil.info(`${TAG} Picker item changed, value: ${value}, index: ${index} `); }); - Text(this.text).fontSize($r("app.float.font_24")).fontWeight(FontWeight.Regular).height($r("app.float.wh_value_21_5")) - }.margin({ right: this.isVisibility ? this.marginRight : $r("app.float.distance_0") }); + Text(this.text).fontSize($r('app.float.font_24')).fontWeight(FontWeight.Regular).height($r('app.float.wh_value_21_5')) + }.margin({ right: this.isVisibility ? this.marginRight : $r('app.float.distance_0') }); Column() { - Text(':').fontSize($r("app.float.font_40")).fontWeight(FontWeight.Regular).fontColor($r("app.color.font_color")); - Text('').fontSize($r("app.float.font_24")).fontWeight(FontWeight.Regular).height($r("app.float.wh_value_21_5")); + Text(':').fontSize($r('app.float.font_40')).fontWeight(FontWeight.Regular).fontColor($r('app.color.font_color')); + Text('').fontSize($r('app.float.font_24')).fontWeight(FontWeight.Regular).height($r('app.float.wh_value_21_5')); }.margin({ right: this.marginRight }) .visibility(this.isVisibility ? Visibility.Visible : Visibility.None); } diff --git a/feature/timer/src/main/ets/components/TimerView.ets b/feature/timer/src/main/ets/components/TimerView.ets index 2355e6d..4f53639 100644 --- a/feature/timer/src/main/ets/components/TimerView.ets +++ b/feature/timer/src/main/ets/components/TimerView.ets @@ -51,9 +51,9 @@ export struct TimerView { .onReady(() => { this.drawDials(); }) - .backgroundColor($r("app.color.background_color_white")) + .backgroundColor($r('app.color.background_color_white')) .borderRadius(this.sSize / 2) - .shadow({ radius: ConfigData.SHADOW_RADIUS * this.mScale, color: $r("app.color.shadow_color") }); + .shadow({ radius: ConfigData.SHADOW_RADIUS * this.mScale, color: $r('app.color.shadow_color') }); Canvas(this.minutesContext) .height(this.sSize) .aspectRatio(1.0) @@ -142,9 +142,9 @@ export struct TimerView { this.dialsContext.restore(); this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR; // Font style - this.dialsContext.font = "normal 500 " + vp2px(ConfigData.SECOND_FONT_SIZE * this.mScale) + 'px'; - this.dialsContext.textBaseline = "middle"; - this.dialsContext.textAlign = "center"; + this.dialsContext.font = 'normal 500 ' + vp2px(ConfigData.SECOND_FONT_SIZE * this.mScale) + 'px'; + this.dialsContext.textBaseline = 'middle'; + this.dialsContext.textAlign = 'center'; // Drawing scale for (let n = 0; n < 60; n++) { // Gets an Angle of 60 scales @@ -195,7 +195,7 @@ export struct TimerView { this.dialsContext.fill(); this.dialsContext.restore(); // Font style - this.dialsContext.font = "normal 400 " + vp2px(ConfigData.MINUTE_FONT_SIZE * this.mScale) + 'px'; + this.dialsContext.font = 'normal 400 ' + vp2px(ConfigData.MINUTE_FONT_SIZE * this.mScale) + 'px'; // Drawing scale for (let n = 0; n < 30; n++) { this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR; diff --git a/feature/timer/src/main/ets/controller/TimerController.ets b/feature/timer/src/main/ets/controller/TimerController.ets index 56ce224..402bee8 100644 --- a/feature/timer/src/main/ets/controller/TimerController.ets +++ b/feature/timer/src/main/ets/controller/TimerController.ets @@ -16,7 +16,8 @@ import { ConfigData, LogUtil } from '@ohos/common'; import data_preferences from '@ohos.data.preferences'; -const TAG = "TimerController : "; +const TAG = 'TimerController : '; +const STORE_NAME = 'myClockStore'; export enum TimerState { /** @@ -46,6 +47,11 @@ export class TimerController { private stateUpdateListener: (TimerState) => void = undefined; private timeListUpdateListener: (timeList: Array, lastTimeMs: number) => void = undefined; private preferences: data_preferences.Preferences = undefined; + private startTimestampStr: string = `startTimestamp`; + private stateStr: string = `state`; + private timeListStr: string = `timeList`; + private lastTimeMsStr: string = `lastTimeMs`; + private beforePauseTimeStr: string = `beforePauseTime`; /** * Timer start @@ -63,7 +69,7 @@ export class TimerController { this.notifyTimeChanges(); }, ConfigData.NOTIFY_INTERVAL_MS); if (this.preferences) { - await this.preferences.put("startTimestamp", this.startTimestamp); + await this.preferences.put(this.startTimestampStr, this.startTimestamp); } this.state = TimerState.RUNNING; this.notifyStateChanges(); @@ -81,7 +87,7 @@ export class TimerController { this.notifierId = -1; this.state = TimerState.PAUSED; if (this.preferences) { - await this.preferences.put("beforePauseTime", this.beforePauseTime); + await this.preferences.put(this.beforePauseTimeStr, this.beforePauseTime); } this.notifyTimeChanges(); this.notifyStateChanges(); @@ -110,13 +116,13 @@ export class TimerController { */ public async reload() { LogUtil.info(`${TAG} Read the previous data `); - this.preferences = await data_preferences.getPreferences(globalThis.abilityContext, 'myClockStore'); - this.state = await this.preferences.get("state", TimerState.IDLE); - this.lastTimeMs = await this.preferences.get("lastTimeMs", 0); - this.beforePauseTime = await this.preferences.get("beforePauseTime", 0); - this.startTimestamp = await this.preferences.get("startTimestamp", 0); + this.preferences = await data_preferences.getPreferences(globalThis.abilityContext, STORE_NAME); + this.state = await this.preferences.get(this.stateStr, TimerState.IDLE); + this.lastTimeMs = await this.preferences.get(this.lastTimeMsStr, 0); + this.beforePauseTime = await this.preferences.get(this.beforePauseTimeStr, 0); + this.startTimestamp = await this.preferences.get(this.startTimestampStr, 0); - let timeList = await this.preferences.get("timeList", 0); + let timeList = await this.preferences.get(this.timeListStr, 0); if (timeList == 0) { this.timeList = []; } else { @@ -178,8 +184,8 @@ export class TimerController { } if (this.preferences) { //@ts-ignore - await this.preferences.put("timeList", this.timeList); - await this.preferences.put("lastTimeMs", this.lastTimeMs); + await this.preferences.put(this.timeListStr, this.timeList); + await this.preferences.put(this.lastTimeMsStr, this.lastTimeMs); this.flush(); } } @@ -193,7 +199,7 @@ export class TimerController { this.stateUpdateListener(this.state); } if (this.preferences) { - await this.preferences.put("state", this.state); + await this.preferences.put(this.stateStr, this.state); this.flush(); } } @@ -204,10 +210,10 @@ export class TimerController { private flush() { this.preferences.flush(function (err) { if (err) { - console.warn("Failed flush. Cause: " + err); + console.warn('Failed flush. Cause: ' + err); return; } - console.warn("Succeeded flush."); + console.warn('Succeeded flush.'); }) } diff --git a/product/pc/src/main/ets/pages/Countdown.ets b/product/pc/src/main/ets/pages/Countdown.ets index a88bc98..bac6986 100644 --- a/product/pc/src/main/ets/pages/Countdown.ets +++ b/product/pc/src/main/ets/pages/Countdown.ets @@ -18,7 +18,7 @@ import { ImageComponent, ConfigData } from '@ohos/common'; @Component export struct CountDown { - private headName: ResourceStr = $r("app.string.timer_clock"); + private headName: ResourceStr = $r('app.string.timer_clock'); private controller: CountdownController = new CountdownController(); private viewSize: number = 232; private originRadius: number = 5; @@ -39,13 +39,13 @@ export struct CountDown { Column() { Row() { Text(this.headName) - .fontSize($r("app.float.font_30")) + .fontSize($r('app.float.font_30')) .fontWeight(FontWeight.Regular) - .fontColor($r("app.color.text_color")) - .lineHeight($r("app.float.wh_value_21")); + .fontColor($r('app.color.text_color')) + .lineHeight($r('app.float.wh_value_21')); }.width(ConfigData.WH_100_100) - .padding({ left: $r("app.float.wh_value_24") }) - .height($r("app.float.wh_value_28")); + .padding({ left: $r('app.float.wh_value_24') }) + .height($r('app.float.wh_value_28')); Column() { CountdownView({ @@ -58,25 +58,25 @@ export struct CountDown { scaleHeight: this.scaleHeight, scalePadding: this.scalePadding }); - }.margin({ top: $r("app.float.wh_value_38"), bottom: $r("app.float.wh_value_38") }); + }.margin({ top: $r('app.float.wh_value_38'), bottom: $r('app.float.wh_value_38') }); Column() { Text(this.hour + ':' + this.minute + ':' + this.second) - .lineHeight($r("app.float.wh_value_16")) - .fontColor($r("app.color.text_color")) + .lineHeight($r('app.float.wh_value_16')) + .fontColor($r('app.color.text_color')) .fontWeight(FontWeight.Regular) - .fontSize($r("app.float.font_20")); + .fontSize($r('app.float.font_20')); }.width(ConfigData.WH_100_100); } .height(ConfigData.WH_100_100) - .width($r("app.float.wh_value_304")); + .width($r('app.float.wh_value_304')); - Divider().vertical(true).width($r("app.float.wh_value_0_5")); + Divider().vertical(true).width($r('app.float.wh_value_0_5')); Column() { Column() { TimeSelectView({ - marginRight: $r("app.float.distance_19"), - dividerMargin: $r("app.float.distance_19"), + marginRight: $r('app.float.distance_19'), + dividerMargin: $r('app.float.distance_19'), hour: $hour, minute: $minute, second: $second, @@ -86,19 +86,19 @@ export struct CountDown { } .justifyContent(FlexAlign.Center) .visibility((this.state == CountdownState.IDLE || this.state == CountdownState.PREPARED) ? Visibility.Visible : Visibility.Hidden) - .padding($r("app.float.distance_12")) - .height($r("app.float.wh_value_324")) + .padding($r('app.float.distance_12')) + .height($r('app.float.wh_value_324')) .flexShrink(1); Row() { Row() { ImageComponent({ - color: $r("app.color.white"), - imageSrc: $r("app.media.ic_clock_refresh"), + color: $r('app.color.white'), + imageSrc: $r('app.media.ic_clock_refresh'), imgLength: this.imgLength }); } - .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r('app.float.opacity_4') : $r('app.float.opacity_full')) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { this.controller.reset(); @@ -106,12 +106,12 @@ export struct CountDown { Row() { ImageComponent({ - color: $r("app.color.selected_text_color"), + color: $r('app.color.selected_text_color'), imageSrc: this.state == CountdownState.RUNNING ? $r('app.media.ic_clock_suspend') : $r('app.media.ic_clock_play'), imgLength: this.imgLength }); } - .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r('app.float.opacity_4') : $r('app.float.opacity_full')) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { if (this.state == CountdownState.PREPARED) { @@ -126,7 +126,7 @@ export struct CountDown { Row() { ImageComponent({ - color: $r("app.color.white"), + color: $r('app.color.white'), imageSrc: $r('app.media.ic_clock_sound'), imgLength: this.imgLength }); @@ -134,14 +134,14 @@ export struct CountDown { .onClick(() => { }); } - .height($r("app.float.wh_value_24")) + .height($r('app.float.wh_value_24')) .width(ConfigData.WH_100_100) .justifyContent(FlexAlign.SpaceBetween) - .margin({ bottom: $r("app.float.distance_10"), top: $r("app.float.distance_4") }) - .padding({ left: $r("app.float.distance_84"), right: $r("app.float.distance_84") }); + .margin({ bottom: $r('app.float.distance_10'), top: $r('app.float.distance_4') }) + .padding({ left: $r('app.float.distance_84'), right: $r('app.float.distance_84') }); } .height(ConfigData.WH_100_100) - .width($r("app.float.wh_value_275_5")); + .width($r('app.float.wh_value_275_5')); } } diff --git a/product/pc/src/main/ets/pages/index.ets b/product/pc/src/main/ets/pages/index.ets index f2f63f3..c503e2c 100644 --- a/product/pc/src/main/ets/pages/index.ets +++ b/product/pc/src/main/ets/pages/index.ets @@ -22,19 +22,19 @@ import { CountDown } from './Countdown'; struct Index { featureList: Array = [ { - name: $r("app.string.alarm_clock"), - icon: $r("app.media.ic_clock_clock"), - selectedIcon: $r("app.media.ic_clock_clock_click") + name: $r('app.string.alarm_clock'), + icon: $r('app.media.ic_clock_clock'), + selectedIcon: $r('app.media.ic_clock_clock_click') }, { - name: $r("app.string.stopwatch"), - icon: $r("app.media.ic_clock_timer"), - selectedIcon: $r("app.media.ic_clock_timer_click") + name: $r('app.string.stopwatch'), + icon: $r('app.media.ic_clock_timer'), + selectedIcon: $r('app.media.ic_clock_timer_click') }, { - name: $r("app.string.timer_clock"), - icon: $r("app.media.ic_clock_second_chronograph"), - selectedIcon: $r("app.media.ic_clock_second_chronograph_click") + name: $r('app.string.timer_clock'), + icon: $r('app.media.ic_clock_second_chronograph'), + selectedIcon: $r('app.media.ic_clock_second_chronograph_click') }, ]; @State featureIndex: number = 1; @@ -47,12 +47,12 @@ struct Index { }), item => { Column() { Image(this.featureIndex == item.i ? item.data.selectedIcon : item.data.icon) - .width($r("app.float.wh_value_12")) - .height($r("app.float.wh_value_12")) + .width($r('app.float.wh_value_12')) + .height($r('app.float.wh_value_12')) Text(item.data.name) - .fontColor(this.featureIndex == item.i ? $r("app.color.selected_text_color") : $r("app.color.text_color")) - .fontSize($r("app.float.font_10")) - .margin({ top: $r("app.float.distance_1") }) + .fontColor(this.featureIndex == item.i ? $r('app.color.selected_text_color') : $r('app.color.text_color')) + .fontSize($r('app.float.font_10')) + .margin({ top: $r('app.float.distance_1') }) } .onClick(() => { this.featureIndex = item.i; @@ -60,11 +60,11 @@ struct Index { }, item => item.i) } - .backgroundColor($r("app.color.background_color_white")) - .padding({ top: $r("app.float.wh_value_118"), bottom: $r("app.float.wh_value_118") }) + .backgroundColor($r('app.color.background_color_white')) + .padding({ top: $r('app.float.wh_value_118'), bottom: $r('app.float.wh_value_118') }) .height(ConfigData.WH_100_100) .justifyContent(FlexAlign.SpaceBetween) - .width($r("app.float.wh_value_60")) + .width($r('app.float.wh_value_60')) Row() { Column() { @@ -78,7 +78,7 @@ struct Index { .width(ConfigData.WH_100_100) .height(ConfigData.WH_100_100) .flexShrink(1) - }.backgroundColor($r("app.color.background_color")) + }.backgroundColor($r('app.color.background_color')) .width(ConfigData.WH_100_100) .height(ConfigData.WH_100_100) } diff --git a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets index af9368f..04d8cae 100644 --- a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer"; +import { TimerController } from '@ohos/timer'; import { TimerUtil, ConfigData } from '@ohos/common'; @Component @@ -31,15 +31,15 @@ export struct CurrentTimeDisplay { build() { Column() { Text(TimerUtil.timeFormat(this.currentTime)) - .lineHeight($r("app.float.wh_value_16")) - .fontColor($r("app.color.text_color")) + .lineHeight($r('app.float.wh_value_16')) + .fontColor($r('app.color.text_color')) .fontWeight(500) - .fontSize($r("app.float.font_20")) + .fontSize($r('app.float.font_20')) Text(TimerUtil.timeFormat(this.currentTime - this.lastTimeMs)) - .lineHeight($r("app.float.wh_value_12")) - .fontColor($r("app.color.text_color")) - .opacity($r("app.float.opacity_6")) - .fontSize($r("app.float.font_14")) + .lineHeight($r('app.float.wh_value_12')) + .fontColor($r('app.color.text_color')) + .opacity($r('app.float.opacity_6')) + .fontSize($r('app.float.font_14')) .visibility(this.lastTimeMs > 0 ? Visibility.Visible : Visibility.Hidden) }.width(ConfigData.WH_100_100) } diff --git a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets index 5a234a6..5fea602 100644 --- a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets @@ -30,40 +30,40 @@ export struct TimeOfRecord { Row() { Row() { Text(TimerUtil.addZero(this.timeList.length - item.i)) - .fontColor($r("app.color.text_color")) - .fontSize($r("app.float.font_14")) + .fontColor($r('app.color.text_color')) + .fontSize($r('app.float.font_14')) .fontWeight(500) - Text("+" + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) - .width($r("app.float.wh_value_60")) + Text('+' + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) + .width($r('app.float.wh_value_60')) .textAlign(TextAlign.Center) - .fontSize($r("app.float.font_14")) - .fontColor($r("app.color.text_color")) - .opacity($r("app.float.opacity_6")) + .fontSize($r('app.float.font_14')) + .fontColor($r('app.color.text_color')) + .opacity($r('app.float.opacity_6')) } - .width($r("app.float.wh_value_151")) + .width($r('app.float.wh_value_151')) .justifyContent(FlexAlign.SpaceBetween) Text(TimerUtil.timeFormat(item.data)) - .fontSize($r("app.float.font_14")) - .fontColor($r("app.color.text_color")) + .fontSize($r('app.float.font_14')) + .fontColor($r('app.color.text_color')) .fontWeight(500) }.width(ConfigData.WH_100_100) .height(ConfigData.WH_100_100) .justifyContent(FlexAlign.SpaceBetween) - .padding({ left: $r("app.float.distance_12"), right: $r("app.float.distance_12") }) + .padding({ left: $r('app.float.distance_12'), right: $r('app.float.distance_12') }) } - .height($r("app.float.wh_value_28")) + .height($r('app.float.wh_value_28')) .width(ConfigData.WH_100_100) .clip(true) }, item => item.i) } - .backgroundColor($r("app.color.background_color_white")) + .backgroundColor($r('app.color.background_color_white')) - .borderRadius($r("app.float.distance_12")) - .margin({ top: $r("app.float.distance_40") }) + .borderRadius($r('app.float.distance_12')) + .margin({ top: $r('app.float.distance_40') }) - }.padding($r("app.float.distance_12")) - .height($r("app.float.wh_value_324")) + }.padding($r('app.float.distance_12')) + .height($r('app.float.wh_value_324')) .flexShrink(1) } } \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/timer/Timer.ets b/product/pc/src/main/ets/pages/timer/Timer.ets index 58ca103..f9fe9f0 100644 --- a/product/pc/src/main/ets/pages/timer/Timer.ets +++ b/product/pc/src/main/ets/pages/timer/Timer.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer"; +import { TimerController } from '@ohos/timer'; import { ConfigData } from '@ohos/common'; import { TimerClock } from './TimerClock'; import { CurrentTimeDisplay } from './CurrentTimeDisplay'; @@ -40,31 +40,31 @@ export struct Timer { Row() { Column() { Row() { - Text($r("app.string.stopwatch")) - .fontSize($r("app.float.font_30")) + Text($r('app.string.stopwatch')) + .fontSize($r('app.float.font_30')) .fontWeight(500) - .fontColor($r("app.color.text_color")) - .lineHeight($r("app.float.wh_value_21")) + .fontColor($r('app.color.text_color')) + .lineHeight($r('app.float.wh_value_21')) }.width(ConfigData.WH_100_100) - .padding({ left: $r("app.float.wh_value_24") }) - .height($r("app.float.wh_value_28")) + .padding({ left: $r('app.float.wh_value_24') }) + .height($r('app.float.wh_value_28')) Column() { TimerClock({ timerController: this.timerController }) - }.margin({ top: $r("app.float.wh_value_38"), bottom: $r("app.float.wh_value_38") }) + }.margin({ top: $r('app.float.wh_value_38'), bottom: $r('app.float.wh_value_38') }) CurrentTimeDisplay({ timerController: this.timerController, lastTimeMs: this.lastTimeMs }) } .height(ConfigData.WH_100_100) - .width($r("app.float.wh_value_304")) + .width($r('app.float.wh_value_304')) - Divider().vertical(true).width($r("app.float.wh_value_0_5")).opacity($r("app.float.opacity_1")) + Divider().vertical(true).width($r('app.float.wh_value_0_5')).opacity($r('app.float.opacity_1')) Column() { TimeOfRecord({ timeList: this.timeList, lastTimeMs: this.lastTimeMs }) TimerControl({ timerController: this.timerController, timeList: this.timeList }) } .height(ConfigData.WH_100_100) - .width($r("app.float.wh_value_275_5")) + .width($r('app.float.wh_value_275_5')) } } } \ No newline at end of file diff --git a/product/pc/src/main/ets/pages/timer/TimerClock.ets b/product/pc/src/main/ets/pages/timer/TimerClock.ets index 6845169..61cf2f4 100644 --- a/product/pc/src/main/ets/pages/timer/TimerClock.ets +++ b/product/pc/src/main/ets/pages/timer/TimerClock.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerView, TimerController } from "@ohos/timer"; +import { TimerView, TimerController } from '@ohos/timer'; const CLOCK_SIZE = 232; diff --git a/product/pc/src/main/ets/pages/timer/TimerControl.ets b/product/pc/src/main/ets/pages/timer/TimerControl.ets index ae32529..bd31018 100644 --- a/product/pc/src/main/ets/pages/timer/TimerControl.ets +++ b/product/pc/src/main/ets/pages/timer/TimerControl.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerController, TimerState } from "@ohos/timer"; +import { TimerController, TimerState } from '@ohos/timer'; import { ImageComponent, ConfigData } from '@ohos/common'; const DEFAULT_ICON_SIZE: number = 12; @@ -34,12 +34,12 @@ export struct TimerControl { Row() { Row() { ImageComponent({ - color: $r("app.color.white"), - imageSrc: $r("app.media.ic_clock_refresh"), + color: $r('app.color.white'), + imageSrc: $r('app.media.ic_clock_refresh'), imgLength: DEFAULT_ICON_SIZE }) } - .opacity(this.state == TimerState.PAUSED ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .opacity(this.state == TimerState.PAUSED ? $r('app.float.opacity_full') : $r('app.float.opacity_4')) .enabled(this.state == TimerState.PAUSED) .onClick(() => { this.timerController.reset() @@ -47,10 +47,10 @@ export struct TimerControl { Row() { ImageComponent({ - color: $r("app.color.selected_text_color"), + color: $r('app.color.selected_text_color'), imageSrc: this.state == TimerState.RUNNING ? - $r("app.media.ic_clock_suspend") : - $r("app.media.ic_clock_play"), imgLength: DEFAULT_ICON_SIZE + $r('app.media.ic_clock_suspend') : + $r('app.media.ic_clock_play'), imgLength: DEFAULT_ICON_SIZE }) }.onClick(() => { if (this.state == TimerState.IDLE) { @@ -64,22 +64,22 @@ export struct TimerControl { Row() { ImageComponent({ - color: $r("app.color.white"), - imageSrc: $r("app.media.ic_clock_timer2"), + color: $r('app.color.white'), + imageSrc: $r('app.media.ic_clock_timer2'), imgLength: DEFAULT_ICON_SIZE }) } - .opacity(this.state == TimerState.RUNNING ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .opacity(this.state == TimerState.RUNNING ? $r('app.float.opacity_full') : $r('app.float.opacity_4')) .enabled(this.state == TimerState.RUNNING) .onClick(() => { this.timerController.writeTime(); }) } - .height($r("app.float.wh_value_24")) + .height($r('app.float.wh_value_24')) .width(ConfigData.WH_100_100) .justifyContent(FlexAlign.SpaceBetween) - .margin({ bottom: $r("app.float.distance_10"), top: $r("app.float.distance_4") }) - .padding({ left: $r("app.float.distance_84"), right: $r("app.float.distance_84") }) - .shadow({ radius: $r("app.float.wh_value_28"), offsetY: -60, color: $r("app.color.background_color") }) + .margin({ bottom: $r('app.float.distance_10'), top: $r('app.float.distance_4') }) + .padding({ left: $r('app.float.distance_84'), right: $r('app.float.distance_84') }) + .shadow({ radius: $r('app.float.wh_value_28'), offsetY: -60, color: $r('app.color.background_color') }) } } \ No newline at end of file diff --git a/product/pc/src/ohosTest/ets/test/Ability.test.ets b/product/pc/src/ohosTest/ets/test/Ability.test.ets index df49ed0..b5c8386 100644 --- a/product/pc/src/ohosTest/ets/test/Ability.test.ets +++ b/product/pc/src/ohosTest/ets/test/Ability.test.ets @@ -3,7 +3,7 @@ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from export default function abilityTest() { describe('ActsAbilityTest', function () { it('assertContain',0, function () { - console.info("it begin") + console.info('it begin') let a = 'abc' let b = 'b' expect(a).assertContain(b) diff --git a/product/phone/src/main/ets/pages/Countdown.ets b/product/phone/src/main/ets/pages/Countdown.ets index e71eaf5..1cf9584 100644 --- a/product/phone/src/main/ets/pages/Countdown.ets +++ b/product/phone/src/main/ets/pages/Countdown.ets @@ -18,7 +18,7 @@ import { ImageComponent, ConfigData } from '@ohos/common'; @Component export struct CountDown { - private headName: ResourceStr = $r("app.string.timer_clock"); + private headName: ResourceStr = $r('app.string.timer_clock'); private controller: CountdownController = new CountdownController(); private viewSize: number = 373.5; @State totalTime: number = 0; @@ -32,13 +32,13 @@ export struct CountDown { Column() { Row() { Text(this.headName) - .fontSize($r("app.float.font_48")) - .fontColor($r("app.color.text_color")) - .lineHeight($r("app.float.wh_value_44")) + .fontSize($r('app.float.font_48')) + .fontColor($r('app.color.text_color')) + .lineHeight($r('app.float.wh_value_44')) .fontWeight(FontWeight.Regular) .textOverflow({ overflow: TextOverflow.Ellipsis }) .textAlign(TextAlign.Center) - .margin({ top: $r("app.float.distance_18_5"), bottom: $r("app.float.distance_12") }); + .margin({ top: $r('app.float.distance_18_5'), bottom: $r('app.float.distance_12') }); } .width(ConfigData.WH_100_100); @@ -52,12 +52,12 @@ export struct CountDown { state: this.state }); } - .margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_16") }); + .margin({ bottom: $r('app.float.distance_16'), top: $r('app.float.distance_16') }); Text(this.hour + ':' + this.minute + ':' + this.second) - .fontSize($r("app.float.font_40")) - .fontColor($r("app.color.text_color")) - .lineHeight($r("app.float.wh_value_32")) + .fontSize($r('app.float.font_40')) + .fontColor($r('app.color.text_color')) + .lineHeight($r('app.float.wh_value_32')) .fontWeight(FontWeight.Regular); Column() { @@ -68,19 +68,19 @@ export struct CountDown { callBack: this.timeSelectCallBack }); } - .margin({ top: $r("app.float.distance_42"), bottom: $r("app.float.distance_24") }) + .margin({ top: $r('app.float.distance_42'), bottom: $r('app.float.distance_24') }) .visibility((this.state == CountdownState.IDLE || this.state == CountdownState.PREPARED) ? Visibility.Visible : Visibility.None); } } - .height($r("app.float.wh_value_516")) + .height($r('app.float.wh_value_516')) .width(ConfigData.WH_100_100) .scrollBar(BarState.Off); Row() { Row() { - ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_refresh') }); + ImageComponent({ color: $r('app.color.white'), imageSrc: $r('app.media.ic_clock_refresh') }); } - .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r('app.float.opacity_4') : $r('app.float.opacity_full')) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { this.controller.reset(); @@ -88,12 +88,12 @@ export struct CountDown { Row() { ImageComponent({ - color: $r("app.color.selected_text_color"), + color: $r('app.color.selected_text_color'), imageSrc: this.state == CountdownState.RUNNING ? $r('app.media.ic_clock_suspend') : $r('app.media.ic_clock_play') }); } - .margin({ left: $r("app.float.distance_48"), right: $r("app.float.distance_48") }) - .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r("app.float.opacity_4") : $r("app.float.opacity_full")) + .margin({ left: $r('app.float.distance_48'), right: $r('app.float.distance_48') }) + .opacity((this.state == CountdownState.IDLE || this.state == CountdownState.STOPPED) ? $r('app.float.opacity_4') : $r('app.float.opacity_full')) .enabled((this.state == CountdownState.PREPARED || this.state == CountdownState.PAUSED || this.state == CountdownState.RUNNING)) .onClick(() => { if (this.state == CountdownState.PREPARED) { @@ -107,15 +107,15 @@ export struct CountDown { }) Row() { - ImageComponent({ color: $r("app.color.white"), imageSrc: $r('app.media.ic_clock_sound') }); + ImageComponent({ color: $r('app.color.white'), imageSrc: $r('app.media.ic_clock_sound') }); } .onClick(() => { }); - }.margin({ top: $r("app.float.distance_16"), bottom: $r("app.float.distance_16") }); + }.margin({ top: $r('app.float.distance_16'), bottom: $r('app.float.distance_16') }); } .width(ConfigData.WH_100_100) .height(ConfigData.WH_100_100) - .padding({ left: $r("app.float.distance_32"), right: $r("app.float.distance_32") }); + .padding({ left: $r('app.float.distance_32'), right: $r('app.float.distance_32') }); } /** diff --git a/product/phone/src/main/ets/pages/index.ets b/product/phone/src/main/ets/pages/index.ets index 52bcdc1..04657f8 100644 --- a/product/phone/src/main/ets/pages/index.ets +++ b/product/phone/src/main/ets/pages/index.ets @@ -22,19 +22,19 @@ import { CountDown } from './Countdown'; struct Index { featureList: Array = [ { - name: $r("app.string.alarm_clock"), - icon: $r("app.media.ic_clock_clock"), - selectedIcon: $r("app.media.ic_clock_clock_click") + name: $r('app.string.alarm_clock'), + icon: $r('app.media.ic_clock_clock'), + selectedIcon: $r('app.media.ic_clock_clock_click') }, { - name: $r("app.string.stopwatch"), - icon: $r("app.media.ic_clock_timer"), - selectedIcon: $r("app.media.ic_clock_timer_click") + name: $r('app.string.stopwatch'), + icon: $r('app.media.ic_clock_timer'), + selectedIcon: $r('app.media.ic_clock_timer_click') }, { - name: $r("app.string.timer_clock"), - icon: $r("app.media.ic_clock_second_chronograph"), - selectedIcon: $r("app.media.ic_clock_second_chronograph_click") + name: $r('app.string.timer_clock'), + icon: $r('app.media.ic_clock_second_chronograph'), + selectedIcon: $r('app.media.ic_clock_second_chronograph_click') }, ]; @State featureIndex: number = 1; @@ -60,24 +60,24 @@ struct Index { }), item => { Column() { Image(this.featureIndex == item.i ? item.data.selectedIcon : item.data.icon) - .width($r("app.float.wh_value_32")) - .height($r("app.float.wh_value_32")) + .width($r('app.float.wh_value_32')) + .height($r('app.float.wh_value_32')) Text(item.data.name) - .fontColor(this.featureIndex == item.i ? $r("app.color.selected_text_color") : $r("app.color.text_color")) - .fontSize($r("app.float.font_24")) - .margin({ top: $r("app.float.distance_3") }) + .fontColor(this.featureIndex == item.i ? $r('app.color.selected_text_color') : $r('app.color.text_color')) + .fontSize($r('app.float.font_24')) + .margin({ top: $r('app.float.distance_3') }) }.width(ConfigData.WH_33_100) .onClick(() => { this.featureIndex = item.i; }) }, item => item.i) } - .height($r("app.float.wh_value_75")) + .height($r('app.float.wh_value_75')) .width(ConfigData.WH_100_100) .justifyContent(FlexAlign.Center) } .width(ConfigData.WH_100_100) .height(ConfigData.WH_100_100) - .backgroundColor($r("app.color.background_color")) + .backgroundColor($r('app.color.background_color')) } } \ No newline at end of file diff --git a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets index 8409051..2be98e6 100644 --- a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer"; +import { TimerController } from '@ohos/timer'; import { TimerUtil, ConfigData } from '@ohos/common'; @Component @@ -31,15 +31,15 @@ export struct CurrentTimeDisplay { build() { Column() { Text(TimerUtil.timeFormat(this.currentTime)) - .lineHeight($r("app.float.wh_value_32")) - .fontColor($r("app.color.text_color")) + .lineHeight($r('app.float.wh_value_32')) + .fontColor($r('app.color.text_color')) .fontWeight(500) - .fontSize($r("app.float.font_40")) + .fontSize($r('app.float.font_40')) Text(TimerUtil.timeFormat(this.currentTime - this.lastTimeMs)) - .lineHeight($r("app.float.wh_value_32")) - .fontColor($r("app.color.text_color")) - .opacity($r("app.float.opacity_6")) - .fontSize($r("app.float.font_28")) + .lineHeight($r('app.float.wh_value_32')) + .fontColor($r('app.color.text_color')) + .opacity($r('app.float.opacity_6')) + .fontSize($r('app.float.font_28')) .visibility(this.lastTimeMs > 0 ? Visibility.Visible : Visibility.Hidden) }.width(ConfigData.WH_100_100) } diff --git a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets index 3a4c397..48b50fc 100644 --- a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets @@ -30,42 +30,42 @@ export struct TimeOfRecord { Row() { Row() { Text(TimerUtil.addZero(this.timeList.length - item.i)) - .fontSize($r("app.float.font_28")) - .fontColor($r("app.color.text_color")) + .fontSize($r('app.float.font_28')) + .fontColor($r('app.color.text_color')) .fontWeight(500) - Text("+" + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) - .width($r("app.float.wh_value_150")) + Text('+' + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) + .width($r('app.float.wh_value_150')) .textAlign(TextAlign.Center) - .fontSize($r("app.float.font_28")) - .fontColor($r("app.color.text_color")) - .opacity($r("app.float.opacity_6")) + .fontSize($r('app.float.font_28')) + .fontColor($r('app.color.text_color')) + .opacity($r('app.float.opacity_6')) } - .width($r("app.float.wh_value_280")) + .width($r('app.float.wh_value_280')) .justifyContent(FlexAlign.SpaceBetween) Text(TimerUtil.timeFormat(item.data)) - .fontSize($r("app.float.font_28")) - .fontColor($r("app.color.text_color")) + .fontSize($r('app.float.font_28')) + .fontColor($r('app.color.text_color')) .fontWeight(500) }.width(ConfigData.WH_100_100) .height(ConfigData.WH_100_100) .justifyContent(FlexAlign.SpaceBetween) - .padding({ left: $r("app.float.distance_16"), right: $r("app.float.distance_16") }) + .padding({ left: $r('app.float.distance_16'), right: $r('app.float.distance_16') }) } - .height($r("app.float.wh_value_75")) + .height($r('app.float.wh_value_75')) .width(ConfigData.WH_100_100) .clip(true) }, item => item.i) } - .backgroundColor($r("app.color.background_color_white")) - .borderRadius($r("app.float.distance_32")) - .padding({ top: $r("app.float.distance_6"), bottom: $r("app.float.distance_6") }) + .backgroundColor($r('app.color.background_color_white')) + .borderRadius($r('app.float.distance_32')) + .padding({ top: $r('app.float.distance_6'), bottom: $r('app.float.distance_6') }) } .padding({ - left: $r("app.float.distance_16"), - right: $r("app.float.distance_16"), - top: $r("app.float.distance_8"), - bottom: $r("app.float.distance_8") + left: $r('app.float.distance_16'), + right: $r('app.float.distance_16'), + top: $r('app.float.distance_8'), + bottom: $r('app.float.distance_8') }) .visibility(this.timeList.length > 0 ? Visibility.Visible : Visibility.None) } diff --git a/product/phone/src/main/ets/pages/timer/Timer.ets b/product/phone/src/main/ets/pages/timer/Timer.ets index 849be19..d6d68f2 100644 --- a/product/phone/src/main/ets/pages/timer/Timer.ets +++ b/product/phone/src/main/ets/pages/timer/Timer.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerController } from "@ohos/timer"; +import { TimerController } from '@ohos/timer'; import { ConfigData } from '@ohos/common'; import { TimerClock } from './TimerClock'; import { CurrentTimeDisplay } from './CurrentTimeDisplay'; @@ -39,37 +39,37 @@ export struct Timer { build() { Column() { Row() { - Text($r("app.string.stopwatch")) - .fontSize($r("app.float.font_48")) - .fontColor($r("app.color.text_color")) - .lineHeight($r("app.float.wh_value_44")) + Text($r('app.string.stopwatch')) + .fontSize($r('app.float.font_48')) + .fontColor($r('app.color.text_color')) + .lineHeight($r('app.float.wh_value_44')) .fontWeight(500) .textOverflow({ overflow: TextOverflow.Ellipsis }) .textAlign(TextAlign.Center) - .margin({ top: $r("app.float.distance_18_5"), bottom: $r("app.float.distance_12") }) + .margin({ top: $r('app.float.distance_18_5'), bottom: $r('app.float.distance_12') }) } - .padding({ left: $r("app.float.wh_value_32") }) + .padding({ left: $r('app.float.wh_value_32') }) .width(ConfigData.WH_100_100) List() { ListItem() { TimerClock({ timerController: this.timerController }) - }.margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_16") }) + }.margin({ bottom: $r('app.float.distance_16'), top: $r('app.float.distance_16') }) ListItem() { CurrentTimeDisplay({ timerController: this.timerController, lastTimeMs: this.lastTimeMs }) } .sticky(Sticky.Normal) - .backgroundColor($r("app.color.background_color")) - .shadow({ radius: $r("app.float.wh_value_20"), offsetY: 30, color: $r("app.color.background_color") }) - .margin({ bottom: $r("app.float.distance_8") }) + .backgroundColor($r('app.color.background_color')) + .shadow({ radius: $r('app.float.wh_value_20'), offsetY: 30, color: $r('app.color.background_color') }) + .margin({ bottom: $r('app.float.distance_8') }) ListItem() { TimeOfRecord({ timeList: this.timeList, lastTimeMs: this.lastTimeMs }) } } .width(ConfigData.WH_100_100) - .height($r("app.float.wh_value_526")) + .height($r('app.float.wh_value_526')) .scrollBar(BarState.Off) .edgeEffect(EdgeEffect.None) diff --git a/product/phone/src/main/ets/pages/timer/TimerClock.ets b/product/phone/src/main/ets/pages/timer/TimerClock.ets index d241177..a0d0a6b 100644 --- a/product/phone/src/main/ets/pages/timer/TimerClock.ets +++ b/product/phone/src/main/ets/pages/timer/TimerClock.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerView, TimerController } from "@ohos/timer"; +import { TimerView, TimerController } from '@ohos/timer'; const CLOCK_SIZE = 373.5; diff --git a/product/phone/src/main/ets/pages/timer/TimerControl.ets b/product/phone/src/main/ets/pages/timer/TimerControl.ets index adbd0b1..bdbeb1c 100644 --- a/product/phone/src/main/ets/pages/timer/TimerControl.ets +++ b/product/phone/src/main/ets/pages/timer/TimerControl.ets @@ -13,7 +13,7 @@ * limitations under the License. */ -import { TimerController, TimerState } from "@ohos/timer"; +import { TimerController, TimerState } from '@ohos/timer'; import { ImageComponent, ConfigData } from '@ohos/common'; @Component @@ -31,9 +31,9 @@ export struct TimerControl { build() { Row() { Row() { - ImageComponent({ color: $r("app.color.white"), imageSrc: $r("app.media.ic_clock_refresh") }) + ImageComponent({ color: $r('app.color.white'), imageSrc: $r('app.media.ic_clock_refresh') }) } - .opacity(this.state == TimerState.PAUSED ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .opacity(this.state == TimerState.PAUSED ? $r('app.float.opacity_full') : $r('app.float.opacity_4')) .enabled(this.state == TimerState.PAUSED) .onClick(() => { this.timerController.reset(); @@ -41,10 +41,10 @@ export struct TimerControl { Row() { ImageComponent({ - color: $r("app.color.selected_text_color"), + color: $r('app.color.selected_text_color'), imageSrc: this.state == TimerState.RUNNING ? - $r("app.media.ic_clock_suspend") : - $r("app.media.ic_clock_play") + $r('app.media.ic_clock_suspend') : + $r('app.media.ic_clock_play') }) }.onClick(() => { if (this.state == TimerState.IDLE) { @@ -57,19 +57,19 @@ export struct TimerControl { }) Row() { - ImageComponent({ color: $r("app.color.white"), imageSrc: $r("app.media.ic_clock_timer2") }) + ImageComponent({ color: $r('app.color.white'), imageSrc: $r('app.media.ic_clock_timer2') }) } - .opacity(this.state == TimerState.RUNNING ? $r("app.float.opacity_full") : $r("app.float.opacity_4")) + .opacity(this.state == TimerState.RUNNING ? $r('app.float.opacity_full') : $r('app.float.opacity_4')) .enabled(this.state == TimerState.RUNNING) .onClick(() => { this.timerController.writeTime(); }) } - .height($r("app.float.wh_value_64")) + .height($r('app.float.wh_value_64')) .width(ConfigData.WH_100_100) .justifyContent(FlexAlign.SpaceBetween) - .margin({ bottom: $r("app.float.distance_16"), top: $r("app.float.distance_6") }) - .padding({ left: $r("app.float.distance_96"), right: $r("app.float.distance_96") }) - .shadow({ radius: $r("app.float.wh_value_20"), offsetY: -40, color: $r("app.color.background_color") }) + .margin({ bottom: $r('app.float.distance_16'), top: $r('app.float.distance_6') }) + .padding({ left: $r('app.float.distance_96'), right: $r('app.float.distance_96') }) + .shadow({ radius: $r('app.float.wh_value_20'), offsetY: -40, color: $r('app.color.background_color') }) } } \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/test/Ability.test.ets b/product/phone/src/ohosTest/ets/test/Ability.test.ets index df49ed0..b5c8386 100644 --- a/product/phone/src/ohosTest/ets/test/Ability.test.ets +++ b/product/phone/src/ohosTest/ets/test/Ability.test.ets @@ -3,7 +3,7 @@ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from export default function abilityTest() { describe('ActsAbilityTest', function () { it('assertContain',0, function () { - console.info("it begin") + console.info('it begin') let a = 'abc' let b = 'b' expect(a).assertContain(b) -- Gitee From 008938c5dad9542f337f2af00494177f8b6e67c0 Mon Sep 17 00:00:00 2001 From: liu_gang Date: Mon, 14 Nov 2022 15:01:33 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=AD=94=E9=AC=BC?= =?UTF-8?q?=E6=95=B0=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liu_gang --- .../src/main/ets/components/TimerView.ets | 43 +++++++++++-------- .../src/main/ets/pages/timer/TimeOfRecord.ets | 2 +- .../src/main/ets/pages/timer/TimeOfRecord.ets | 2 +- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/feature/timer/src/main/ets/components/TimerView.ets b/feature/timer/src/main/ets/components/TimerView.ets index 4f53639..f65081f 100644 --- a/feature/timer/src/main/ets/components/TimerView.ets +++ b/feature/timer/src/main/ets/components/TimerView.ets @@ -15,6 +15,11 @@ import { ConfigData } from '@ohos/common'; +const DOUBLE: number = 2; +const TIME_DECIMAL: number = 60; +const MS_DECIMAL: number = 1000; +const FLAG_BIT: number = 5; + @Component export struct TimerView { @Prop currentTime: number; @@ -36,10 +41,10 @@ export struct TimerView { aboutToAppear() { this.mScale = this.sSize / ConfigData.STANDARD_SIZE; - this.mSize = this.sSize / 4; + this.mSize = this.sSize / DOUBLE / DOUBLE; // Get the radius - this.sRadius = this.sSize / 2 - ConfigData.SECOND_DISTANCE * this.mScale; - this.mRadius = this.mSize / 2 - ConfigData.MINUTE_DISTANCE * this.mScale; + this.sRadius = this.sSize / DOUBLE - ConfigData.SECOND_DISTANCE * this.mScale; + this.mRadius = this.mSize / DOUBLE - ConfigData.MINUTE_DISTANCE * this.mScale; } build() { @@ -52,19 +57,19 @@ export struct TimerView { this.drawDials(); }) .backgroundColor($r('app.color.background_color_white')) - .borderRadius(this.sSize / 2) + .borderRadius(this.sSize / DOUBLE) .shadow({ radius: ConfigData.SHADOW_RADIUS * this.mScale, color: $r('app.color.shadow_color') }); Canvas(this.minutesContext) .height(this.sSize) .aspectRatio(1.0) .onReady(() => { - this.drawMinutes(this.currentTime % (60 * 60 * 1000) / (60 * 1000)); + this.drawMinutes(this.currentTime % (TIME_DECIMAL * TIME_DECIMAL * MS_DECIMAL) / (TIME_DECIMAL * MS_DECIMAL)); }); Canvas(this.secondContext) .height(this.sSize) .aspectRatio(1.0) .onReady(() => { - this.drawSecond(this.currentTime % (60 * 1000) / 1000); + this.drawSecond(this.currentTime % (TIME_DECIMAL * MS_DECIMAL) / MS_DECIMAL); }); } } @@ -82,7 +87,7 @@ export struct TimerView { this.secondContext.save(); this.secondContext.strokeStyle = ConfigData.SECOND_HAND_COLOR; // Pointer Angle The second hand is divided into 60 parts - let theta = second * 2 * Math.PI / 60; + let theta = second * DOUBLE * Math.PI / TIME_DECIMAL; this.secondContext.beginPath(); // A pointer to draw let x_move = this.sRadius * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; @@ -106,7 +111,7 @@ export struct TimerView { this.minutesContext.lineCap = 'round'; this.minutesContext.save(); // Pointer Angle The minute hand is divided into 30 parts - let theta = minutes * 2 * Math.PI / 30; + let theta = minutes * DOUBLE * Math.PI / (TIME_DECIMAL / DOUBLE); this.minutesContext.beginPath(); // Start position of scale let x_move = (this.mRadius - ConfigData.MINUTE_POINTER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; @@ -137,7 +142,7 @@ export struct TimerView { this.dialsContext.fillStyle = ConfigData.SECOND_HAND_COLOR; this.dialsContext.beginPath(); - this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y, ConfigData.SECOND_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2); + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y, ConfigData.SECOND_CIRCLE_WIDTH * this.mScale, 0, Math.PI * DOUBLE); this.dialsContext.fill(); this.dialsContext.restore(); this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR; @@ -146,9 +151,9 @@ export struct TimerView { this.dialsContext.textBaseline = 'middle'; this.dialsContext.textAlign = 'center'; // Drawing scale - for (let n = 0; n < 60; n++) { + for (let n = 0; n < TIME_DECIMAL; n++) { // Gets an Angle of 60 scales - let theta = n * (Math.PI * 2) / 60; + let theta = n * (Math.PI * DOUBLE) / TIME_DECIMAL; this.dialsContext.save(); // Setting the scale width this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale; @@ -160,7 +165,7 @@ export struct TimerView { let x_to = (this.sRadius - ConfigData.SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_to = -(this.sRadius - ConfigData.SECOND_TICK_MARK_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; // Integral point calibration - if (n % 5 == 0) { + if (n % FLAG_BIT == 0) { // The scale width of the hour this.dialsContext.lineWidth = ConfigData.HOUR_TICK_MARK_WIDTH * this.mScale; // End position of the mark on the hour @@ -170,7 +175,7 @@ export struct TimerView { let x_time = (this.sRadius - ConfigData.HOUR_SECOND_TIMER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_time = -(this.sRadius - ConfigData.HOUR_SECOND_TIMER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.SECOND_DIALS_CENTER_OFFSET_Y; // Plot the hour - this.dialsContext.fillText(this.times[n / 5] + '', x_time, y_time); + this.dialsContext.fillText(this.times[n / FLAG_BIT] + '', x_time, y_time); } // Draw the scale this.dialsContext.moveTo(x_move, y_move); @@ -187,19 +192,19 @@ export struct TimerView { // Draw the origin this.dialsContext.save(); this.dialsContext.beginPath(); - this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2); + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CIRCLE_WIDTH * this.mScale, 0, Math.PI * DOUBLE); this.dialsContext.fill(); this.dialsContext.fillStyle = ConfigData.CIRCLE_WIDTH_COLOR; this.dialsContext.beginPath(); - this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CENTER_CIRCLE_WIDTH * this.mScale, 0, Math.PI * 2); + this.dialsContext.arc(this.sSize * ConfigData.DIALS_CENTER_OFFSET_X, this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y, ConfigData.MINUTE_CENTER_CIRCLE_WIDTH * this.mScale, 0, Math.PI * DOUBLE); this.dialsContext.fill(); this.dialsContext.restore(); // Font style this.dialsContext.font = 'normal 400 ' + vp2px(ConfigData.MINUTE_FONT_SIZE * this.mScale) + 'px'; // Drawing scale - for (let n = 0; n < 30; n++) { + for (let n = 0; n < (TIME_DECIMAL / DOUBLE); n++) { this.dialsContext.strokeStyle = ConfigData.TICK_MARK_COLOR; - let theta = n * (Math.PI * 2) / 30; + let theta = n * (Math.PI * DOUBLE) / (TIME_DECIMAL / DOUBLE); this.dialsContext.save(); // Scale width this.dialsContext.lineWidth = ConfigData.TICK_MARK_WIDTH * this.mScale; @@ -211,13 +216,13 @@ export struct TimerView { let x_to = (this.mRadius - ConfigData.MINUTE_TICK_MARK_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_to = -(this.mRadius - ConfigData.MINUTE_TICK_MARK_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; // Integral point calibration - if (n % 5 == 0) { + if (n % FLAG_BIT == 0) { this.dialsContext.strokeStyle = ConfigData.HOUR_TICK_MARK_COLOR; // Time position on the hour let x_time = (this.mRadius - ConfigData.HOUR_MINUTE_TIMER_DISTANCE * this.mScale) * Math.sin(theta) + this.sSize * ConfigData.DIALS_CENTER_OFFSET_X; let y_time = -(this.mRadius - ConfigData.HOUR_MINUTE_TIMER_DISTANCE * this.mScale) * Math.cos(theta) + this.sSize * ConfigData.MINUTE_DIALS_CENTER_OFFSET_Y; // Plot the hour - this.dialsContext.fillText(this.minTimes[n / 5] + '', x_time, y_time); + this.dialsContext.fillText(this.minTimes[n / FLAG_BIT] + '', x_time, y_time); } // Draw the scale this.dialsContext.moveTo(x_move, y_move); diff --git a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets index 5fea602..c14fe73 100644 --- a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets @@ -33,7 +33,7 @@ export struct TimeOfRecord { .fontColor($r('app.color.text_color')) .fontSize($r('app.float.font_14')) .fontWeight(500) - Text('+' + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) + Text('+' + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - 1 - item.i -1] : 0))) .width($r('app.float.wh_value_60')) .textAlign(TextAlign.Center) .fontSize($r('app.float.font_14')) diff --git a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets index 48b50fc..fa157dc 100644 --- a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets @@ -33,7 +33,7 @@ export struct TimeOfRecord { .fontSize($r('app.float.font_28')) .fontColor($r('app.color.text_color')) .fontWeight(500) - Text('+' + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - item.i - 2] : 0))) + Text('+' + TimerUtil.timeFormat(item.data - (item.i < this.timeList.length - 1 ? this.timeList[this.timeList.length - 1 - item.i - 1] : 0))) .width($r('app.float.wh_value_150')) .textAlign(TextAlign.Center) .fontSize($r('app.float.font_28')) -- Gitee From d980eb6822a6bc4e6d55577bf78bef9428fc47e0 Mon Sep 17 00:00:00 2001 From: liu_gang Date: Mon, 14 Nov 2022 15:04:10 +0800 Subject: [PATCH 07/19] modify string.json Signed-off-by: liu_gang --- .../src/main/resources/base/element/string.json | 6 +++--- .../src/main/resources/zh_CN/element/string.json | 16 ++++++++++++++++ .../src/main/resources/base/element/string.json | 6 +++--- .../src/main/resources/zh_CN/element/string.json | 16 ++++++++++++++++ .../src/main/resources/base/element/string.json | 2 +- .../src/main/resources/zh_CN/element/string.json | 8 ++++++++ .../src/main/resources/base/element/string.json | 2 +- .../src/main/resources/zh_CN/element/string.json | 8 ++++++++ 8 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 common/src/main/resources/zh_CN/element/string.json create mode 100644 feature/countdown/src/main/resources/zh_CN/element/string.json create mode 100644 product/pc/src/main/resources/zh_CN/element/string.json create mode 100644 product/phone/src/main/resources/zh_CN/element/string.json diff --git a/common/src/main/resources/base/element/string.json b/common/src/main/resources/base/element/string.json index 518dfe5..d2dab5d 100644 --- a/common/src/main/resources/base/element/string.json +++ b/common/src/main/resources/base/element/string.json @@ -6,15 +6,15 @@ }, { "name": "alarm_clock", - "value": "闹钟" + "value": "Alarm clock" }, { "name": "stopwatch", - "value": "秒表" + "value": "stopwatch" }, { "name": "timer_clock", - "value": "计时器" + "value": "hour meter" } ] } diff --git a/common/src/main/resources/zh_CN/element/string.json b/common/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..2e3b29c --- /dev/null +++ b/common/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "alarm_clock", + "value": "闹钟" + }, + { + "name": "stopwatch", + "value": "秒表" + }, + { + "name": "timer_clock", + "value": "计时器" + } + ] +} \ No newline at end of file diff --git a/feature/countdown/src/main/resources/base/element/string.json b/feature/countdown/src/main/resources/base/element/string.json index f2810e5..c66d27f 100644 --- a/feature/countdown/src/main/resources/base/element/string.json +++ b/feature/countdown/src/main/resources/base/element/string.json @@ -6,15 +6,15 @@ }, { "name": "hour", - "value": "时" + "value": "hour" }, { "name": "minute", - "value": "分" + "value": "minute" }, { "name": "second", - "value": "秒" + "value": "minute" } ] } diff --git a/feature/countdown/src/main/resources/zh_CN/element/string.json b/feature/countdown/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..c2af9ff --- /dev/null +++ b/feature/countdown/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "hour", + "value": "时" + }, + { + "name": "minute", + "value": "分" + }, + { + "name": "second", + "value": "秒" + } + ] +} diff --git a/product/pc/src/main/resources/base/element/string.json b/product/pc/src/main/resources/base/element/string.json index b2dcdc7..f0dc461 100644 --- a/product/pc/src/main/resources/base/element/string.json +++ b/product/pc/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "MainAbility_label", - "value": "时钟" + "value": "Clock" } ] } \ No newline at end of file diff --git a/product/pc/src/main/resources/zh_CN/element/string.json b/product/pc/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..4e7d9f8 --- /dev/null +++ b/product/pc/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "MainAbility_label", + "value": "时钟" + } + ] +} \ No newline at end of file diff --git a/product/phone/src/main/resources/base/element/string.json b/product/phone/src/main/resources/base/element/string.json index 9fb9000..b816130 100644 --- a/product/phone/src/main/resources/base/element/string.json +++ b/product/phone/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "MainAbility_label", - "value": "时钟" + "value": "Clock" } ] } \ No newline at end of file diff --git a/product/phone/src/main/resources/zh_CN/element/string.json b/product/phone/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000..4e7d9f8 --- /dev/null +++ b/product/phone/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "MainAbility_label", + "value": "时钟" + } + ] +} \ No newline at end of file -- Gitee From 393639c256ea4b794b28063028bba31765d27e4c Mon Sep 17 00:00:00 2001 From: liu_gang Date: Mon, 14 Nov 2022 15:12:54 +0800 Subject: [PATCH 08/19] adjust parameter position Signed-off-by: liu_gang --- product/pc/src/main/ets/pages/index.ets | 2 +- product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets | 2 +- product/pc/src/main/ets/pages/timer/Timer.ets | 2 +- product/pc/src/main/ets/pages/timer/TimerControl.ets | 2 +- product/phone/src/main/ets/pages/index.ets | 2 +- product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets | 2 +- product/phone/src/main/ets/pages/timer/TimerControl.ets | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/product/pc/src/main/ets/pages/index.ets b/product/pc/src/main/ets/pages/index.ets index c503e2c..953b9e7 100644 --- a/product/pc/src/main/ets/pages/index.ets +++ b/product/pc/src/main/ets/pages/index.ets @@ -20,7 +20,7 @@ import { CountDown } from './Countdown'; @Entry @Component struct Index { - featureList: Array = [ + private featureList: Array = [ { name: $r('app.string.alarm_clock'), icon: $r('app.media.ic_clock_clock'), diff --git a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets index 04d8cae..d032a41 100644 --- a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -19,8 +19,8 @@ import { TimerUtil, ConfigData } from '@ohos/common'; @Component export struct CurrentTimeDisplay { @State currentTime: number = 0; - @Prop lastTimeMs: number; @State timerController: TimerController = new TimerController(); + @Prop lastTimeMs: number; aboutToAppear() { this.timerController.setTimeUpdateListener((currentTimeMs: number) => { diff --git a/product/pc/src/main/ets/pages/timer/Timer.ets b/product/pc/src/main/ets/pages/timer/Timer.ets index f9fe9f0..022c89b 100644 --- a/product/pc/src/main/ets/pages/timer/Timer.ets +++ b/product/pc/src/main/ets/pages/timer/Timer.ets @@ -22,7 +22,7 @@ import { TimerControl } from './TimerControl'; @Component export struct Timer { - timerController: TimerController = new TimerController(); + private timerController: TimerController = new TimerController(); private timeList: Array = []; @State lastTimeMs: number = 0; diff --git a/product/pc/src/main/ets/pages/timer/TimerControl.ets b/product/pc/src/main/ets/pages/timer/TimerControl.ets index bd31018..90cae72 100644 --- a/product/pc/src/main/ets/pages/timer/TimerControl.ets +++ b/product/pc/src/main/ets/pages/timer/TimerControl.ets @@ -21,8 +21,8 @@ const DEFAULT_ICON_SIZE: number = 12; @Component export struct TimerControl { private timerController: TimerController = new TimerController(); - @State state: TimerState = TimerState.IDLE; private timeList: Array = []; + @State state: TimerState = TimerState.IDLE; aboutToAppear() { this.timerController.setStateUpdateListener((state) => { diff --git a/product/phone/src/main/ets/pages/index.ets b/product/phone/src/main/ets/pages/index.ets index 04657f8..832bed1 100644 --- a/product/phone/src/main/ets/pages/index.ets +++ b/product/phone/src/main/ets/pages/index.ets @@ -20,7 +20,7 @@ import { CountDown } from './Countdown'; @Entry @Component struct Index { - featureList: Array = [ + private featureList: Array = [ { name: $r('app.string.alarm_clock'), icon: $r('app.media.ic_clock_clock'), diff --git a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets index 2be98e6..7cd031e 100644 --- a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -19,8 +19,8 @@ import { TimerUtil, ConfigData } from '@ohos/common'; @Component export struct CurrentTimeDisplay { @State currentTime: number = 0; - @Prop lastTimeMs: number; @State timerController: TimerController = new TimerController(); + @Prop lastTimeMs: number; aboutToAppear() { this.timerController.setTimeUpdateListener((currentTimeMs: number) => { diff --git a/product/phone/src/main/ets/pages/timer/TimerControl.ets b/product/phone/src/main/ets/pages/timer/TimerControl.ets index bdbeb1c..8cc9c80 100644 --- a/product/phone/src/main/ets/pages/timer/TimerControl.ets +++ b/product/phone/src/main/ets/pages/timer/TimerControl.ets @@ -19,8 +19,8 @@ import { ImageComponent, ConfigData } from '@ohos/common'; @Component export struct TimerControl { private timerController: TimerController = new TimerController(); - @State state: TimerState = TimerState.IDLE; private timeList: Array = []; + @State state: TimerState = TimerState.IDLE; aboutToAppear() { this.timerController.setStateUpdateListener((state) => { -- Gitee From 59bc9c967fadce5bda99d5bebc5c87a898e167eb Mon Sep 17 00:00:00 2001 From: liu_gang Date: Thu, 24 Nov 2022 11:31:18 +0800 Subject: [PATCH 09/19] Add a blank line between the method description and the input parameter description Signed-off-by: liu_gang --- feature/timer/src/main/ets/components/TimerView.ets | 2 ++ feature/timer/src/main/ets/controller/TimerController.ets | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/feature/timer/src/main/ets/components/TimerView.ets b/feature/timer/src/main/ets/components/TimerView.ets index f65081f..9707774 100644 --- a/feature/timer/src/main/ets/components/TimerView.ets +++ b/feature/timer/src/main/ets/components/TimerView.ets @@ -79,6 +79,7 @@ export struct TimerView { /** * Draw a Second hand + * * @param second */ private drawSecond(second: number): void { @@ -104,6 +105,7 @@ export struct TimerView { /** * Draw a minute hand + * * @param minutes */ private drawMinutes(minutes: number): void { diff --git a/feature/timer/src/main/ets/controller/TimerController.ets b/feature/timer/src/main/ets/controller/TimerController.ets index 402bee8..02ad903 100644 --- a/feature/timer/src/main/ets/controller/TimerController.ets +++ b/feature/timer/src/main/ets/controller/TimerController.ets @@ -219,6 +219,7 @@ export class TimerController { /** * Set listening for state changes + * * @param listener */ public setStateUpdateListener(listener: (TimerState) => void) { @@ -228,6 +229,7 @@ export class TimerController { /** * Set time change listening + * * @param listener */ public setTimeUpdateListener(listener: (currentTimeMs: number) => void) { @@ -237,6 +239,7 @@ export class TimerController { /** * Set time clock change listening + * * @param listener */ public setClockUpdateListener(listener: (currentTimeMs: number) => void) { @@ -246,6 +249,7 @@ export class TimerController { /** * Set the record time list change listening + * * @param listener */ public setTimeListUpdateListener(listener: (timeList: Array, lastTimeMs: number) => void) { -- Gitee From d962fa2701ca7b95be5e5846c30aecdc0df99e3c Mon Sep 17 00:00:00 2001 From: shao_junye Date: Fri, 25 Nov 2022 15:32:41 +0800 Subject: [PATCH 10/19] add countdown ohosTest Signed-off-by: shao_junye --- .../pc/src/ohosTest/ets/test/Ability.test.ets | 519 +++++++++++++++++- .../src/ohosTest/ets/test/Ability.test.ets | 514 ++++++++++++++++- 2 files changed, 1019 insertions(+), 14 deletions(-) diff --git a/product/pc/src/ohosTest/ets/test/Ability.test.ets b/product/pc/src/ohosTest/ets/test/Ability.test.ets index b5c8386..4e443e9 100644 --- a/product/pc/src/ohosTest/ets/test/Ability.test.ets +++ b/product/pc/src/ohosTest/ets/test/Ability.test.ets @@ -1,13 +1,516 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import { TimerController, TimerState } from '@ohos/timer'; +import { CountdownController, CountdownState } from '@ohos/countdown'; +import { TimerUtil } from '@ohos/common'; export default function abilityTest() { - describe('ActsAbilityTest', function () { - it('assertContain',0, function () { - console.info('it begin') - let a = 'abc' - let b = 'b' - expect(a).assertContain(b) - expect(a).assertEqual(a) - }) + describe('ActsAbilityTest', function () { + + it('startState', 0, function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.RUNNING); + testState = false; + } + }); + testState = true; + mTimerController.start(); + }) + + it('startTime', 0, function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(time > 0).assertTrue(); + testState = false; + } + }); + testState = true; + mTimerController.start(); + }) + + it('clockUpdate', 0, function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setClockUpdateListener((time) => { + if (testState) { + expect(time > 0).assertTrue(); + testState = false; + } + }); + testState = true; + mTimerController.start(); + }) + + it('pauseState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.PAUSED); + testState = false; + } + }); + await mTimerController.start(); + testState = true; + setTimeout(async () => { + await mTimerController.pause(); + }, 100); + }) + + it('pauseTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + let testTime = 0; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(testTime).assertEqual(time); + testState = false; + } else { + testTime = time; + } + }); + await mTimerController.start(); + await mTimerController.pause(); + testState = true; + setTimeout(async () => { + await mTimerController.start(); + }, 100); + }) + + it('resetAfterStartState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.IDLE); + testState = false; + } + }); + await mTimerController.start(); + testState = true; + setTimeout(async () => { + await mTimerController.reset(); + }, 100); + }) + + it('resetAfterStartTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(time).assertEqual(0); + testState = false; + } + }); + await mTimerController.start(); + testState = true; + setTimeout(async () => { + await mTimerController.reset(); + }, 100); + }) + + it('reStartState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.RUNNING); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.pause(); + testState = true; + await mTimerController.start(); + }, 100); + }) + + it('reStartStateTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + let testTime = 0; + mTimerController.setTimeUpdateListener((time) => { + if (testTime > 0) { + expect(testTime < time).assertTrue(); + testState = false; + } else if (testState == true) { + testTime = time; + } + }); + await mTimerController.start(); + await mTimerController.pause(); + testState = true; + setTimeout(async () => { + await mTimerController.start(); + }, 100); + }) + + it('resetAfterPauseState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.IDLE); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.pause(); + testState = true; + await mTimerController.reset(); + }, 100); + }) + + it('resetAfterPauseTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(time).assertEqual(0); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.pause(); + testState = true; + await mTimerController.reset(); + }, 100); + }) + + it('writeTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeListUpdateListener((timeList) => { + if (testState) { + expect(timeList.length > 1).assertTrue(); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + testState = true; + await mTimerController.writeTime(); + }, 100); + }) + + it('resetWriteTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeListUpdateListener((timeList) => { + if (testState) { + expect(timeList.length).assertEqual(0); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.writeTime(); + testState = true; + mTimerController.reset(); + }, 100); + }) + + it('addZeroMin', 0, async function () { + let num = 0 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('00') + }) + + it('addZeroMinus', 0, async function () { + let num = -1 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('0-1') + }) + + it('addZeroMax', 0, async function () { + let num = 9 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('09') + }) + + it('addZeroOver', 0, async function () { + let num = 10 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('10') + }) + + it('addZeroNaN', 0, async function () { + let num = NaN + let res = TimerUtil.addZero(num) + expect(res).assertEqual('NaN') + }) + + it('timeFormatZero', 0, async function () { + let num = 0 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.00`) + }) + + it('timeFormatMinus', 0, async function () { + let num = -1 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.00`) + }) + + it('timeFormatMinMs', 0, async function () { + let num = 9 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.00`) + }) + + it('timeFormatMs', 0, async function () { + let num = 10 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.01`) + }) + + it('timeFormatSec', 0, async function () { + let num = 1000 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:01.00`) + }) + + it('timeFormatMin', 0, async function () { + let num = 1000 * 60 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`01:00.00`) + }) + + it('timeFormatHour', 0, async function () { + let num = 1000 * 60 * 60 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`01:00:00.00`) + }) + + it('timeFormatDay', 0, async function () { + let num = 1000 * 60 * 60 * 24 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`01:00:00:00.00`) + }) + }) + + describe('CountdownTest', function () { + it('setTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(totalTimeMs).assertEqual(100); + testState = false; + } + }); + testState = true; + mCountdownController.setTime(100); + }) + + it('setTimeState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.PREPARED); + testState = false; + } + }); + testState = true; + mCountdownController.setTime(100); + }) + + it('startState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.RUNNING); + testState = false; + } + }); + mCountdownController.setTime(100); + testState = true; + mCountdownController.start(); + }) + + it('startTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(currentTimeMs > 0).assertTrue(); + testState = false; + } + }); + mCountdownController.setTime(100); + testState = true; + mCountdownController.start(); + }) + + it('pauseState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.PAUSED); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + testState = true; + setTimeout(() => { + mCountdownController.pause(); + }, 100); + }) + + it('pauseTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + let testTime = 0; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(testTime).assertEqual(totalTimeMs); + testState = false; + } else { + testTime = totalTimeMs; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + mCountdownController.pause(); + testState = true; + setTimeout(() => { + mCountdownController.start(); + }, 100); + }) + + it('resetAfterStartState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.IDLE); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + testState = true; + setTimeout(() => { + mCountdownController.reset(); + }, 100); + }) + + it('resetAfterStartTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(totalTimeMs).assertEqual(0); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + testState = true; + setTimeout(() => { + mCountdownController.reset(); + }, 100); + }) + + it('reStartState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.RUNNING); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + setTimeout(() => { + mCountdownController.pause(); + testState = true; + mCountdownController.start(); + }, 100); + }) + + it('reStartStateTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + let testTime = 0; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testTime > 0) { + expect(testTime < totalTimeMs).assertTrue(); + testState = false; + } else if (testState == true) { + testTime = currentTimeMs; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + mCountdownController.pause(); + testState = true; + setTimeout(() => { + mCountdownController.start(); + }, 100); + }) + + it('resetAfterPauseState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.IDLE); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + setTimeout(() => { + mCountdownController.pause(); + testState = true; + mCountdownController.reset(); + }, 100); + }) + + it('resetAfterPauseTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(totalTimeMs).assertEqual(0); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + setTimeout(() => { + mCountdownController.pause(); + testState = true; + mCountdownController.reset(); + }, 100); }) + }) } \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/test/Ability.test.ets b/product/phone/src/ohosTest/ets/test/Ability.test.ets index b5c8386..e590cc0 100644 --- a/product/phone/src/ohosTest/ets/test/Ability.test.ets +++ b/product/phone/src/ohosTest/ets/test/Ability.test.ets @@ -1,13 +1,515 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import { TimerController, TimerState } from '@ohos/timer'; +import { TimerUtil } from '@ohos/common'; +import { CountdownController, CountdownState } from '@ohos/countdown'; export default function abilityTest() { describe('ActsAbilityTest', function () { - it('assertContain',0, function () { - console.info('it begin') - let a = 'abc' - let b = 'b' - expect(a).assertContain(b) - expect(a).assertEqual(a) + it('startState', 0, function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.RUNNING); + testState = false; + } + }); + testState = true; + mTimerController.start(); + }) + + it('startTime', 0, function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(time > 0).assertTrue(); + testState = false; + } + }); + testState = true; + mTimerController.start(); + }) + + it('clockUpdate', 0, function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setClockUpdateListener((time) => { + if (testState) { + expect(time > 0).assertTrue(); + testState = false; + } + }); + testState = true; + mTimerController.start(); + }) + + it('pauseState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.PAUSED); + testState = false; + } + }); + await mTimerController.start(); + testState = true; + setTimeout(async () => { + await mTimerController.pause(); + }, 100); + }) + + it('pauseTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + let testTime = 0; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(testTime).assertEqual(time); + testState = false; + } else { + testTime = time; + } + }); + await mTimerController.start(); + await mTimerController.pause(); + testState = true; + setTimeout(async () => { + await mTimerController.start(); + }, 100); + }) + + it('resetAfterStartState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.IDLE); + testState = false; + } + }); + await mTimerController.start(); + testState = true; + setTimeout(async () => { + await mTimerController.reset(); + }, 100); + }) + + it('resetAfterStartTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(time).assertEqual(0); + testState = false; + } + }); + await mTimerController.start(); + testState = true; + setTimeout(async () => { + await mTimerController.reset(); + }, 100); + }) + + it('reStartState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.RUNNING); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.pause(); + testState = true; + await mTimerController.start(); + }, 100); + }) + + it('reStartStateTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + let testTime = 0; + mTimerController.setTimeUpdateListener((time) => { + if (testTime > 0) { + expect(testTime < time).assertTrue(); + testState = false; + } else if (testState == true) { + testTime = time; + } + }); + await mTimerController.start(); + await mTimerController.pause(); + testState = true; + setTimeout(async () => { + await mTimerController.start(); + }, 100); + }) + + it('resetAfterPauseState', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(TimerState.IDLE); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.pause(); + testState = true; + await mTimerController.reset(); + }, 100); + }) + + it('resetAfterPauseTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeUpdateListener((time) => { + if (testState) { + expect(time).assertEqual(0); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.pause(); + testState = true; + await mTimerController.reset(); + }, 100); + }) + + it('writeTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeListUpdateListener((timeList) => { + if (testState) { + expect(timeList.length > 1).assertTrue(); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + testState = true; + await mTimerController.writeTime(); + }, 100); + }) + + it('resetWriteTime', 0, async function () { + let mTimerController = new TimerController(); + let testState = false; + mTimerController.setTimeListUpdateListener((timeList) => { + if (testState) { + expect(timeList.length).assertEqual(0); + testState = false; + } + }); + await mTimerController.start(); + setTimeout(async () => { + await mTimerController.writeTime(); + testState = true; + mTimerController.reset(); + }, 100); + }) + + it('addZeroMin', 0, async function () { + let num = 0 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('00') + }) + + it('addZeroMinus', 0, async function () { + let num = -1 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('0-1') + }) + + it('addZeroMax', 0, async function () { + let num = 9 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('09') + }) + + it('addZeroOver', 0, async function () { + let num = 10 + let res = TimerUtil.addZero(num) + expect(res).assertEqual('10') + }) + + it('addZeroNaN', 0, async function () { + let num = NaN + let res = TimerUtil.addZero(num) + expect(res).assertEqual('NaN') + }) + + it('timeFormatZero', 0, async function () { + let num = 0 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.00`) + }) + + it('timeFormatMinus', 0, async function () { + let num = -1 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.00`) + }) + + it('timeFormatMinMs', 0, async function () { + let num = 9 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.00`) + }) + + it('timeFormatMs', 0, async function () { + let num = 10 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:00.01`) + }) + + it('timeFormatSec', 0, async function () { + let num = 1000 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`00:01.00`) + }) + + it('timeFormatMin', 0, async function () { + let num = 1000 * 60 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`01:00.00`) + }) + + it('timeFormatHour', 0, async function () { + let num = 1000 * 60 * 60 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`01:00:00.00`) + }) + + it('timeFormatDay', 0, async function () { + let num = 1000 * 60 * 60 * 24 + let res = TimerUtil.timeFormat(num) + expect(res).assertEqual(`01:00:00:00.00`) + }) + }) + + describe('CountdownTest', function () { + it('setTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(totalTimeMs).assertEqual(100); + testState = false; + } + }); + testState = true; + mCountdownController.setTime(100); + }) + + it('setTimeState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.PREPARED); + testState = false; + } + }); + testState = true; + mCountdownController.setTime(100); + }) + + it('startState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.RUNNING); + testState = false; + } + }); + mCountdownController.setTime(100); + testState = true; + mCountdownController.start(); + }) + + it('startTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(currentTimeMs > 0).assertTrue(); + testState = false; + } + }); + mCountdownController.setTime(100); + testState = true; + mCountdownController.start(); + }) + + it('pauseState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.PAUSED); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + testState = true; + setTimeout(() => { + mCountdownController.pause(); + }, 100); + }) + + it('pauseTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + let testTime = 0; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(testTime).assertEqual(totalTimeMs); + testState = false; + } else { + testTime = totalTimeMs; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + mCountdownController.pause(); + testState = true; + setTimeout(() => { + mCountdownController.start(); + }, 100); + }) + + it('resetAfterStartState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.IDLE); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + testState = true; + setTimeout(() => { + mCountdownController.reset(); + }, 100); + }) + + it('resetAfterStartTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(totalTimeMs).assertEqual(0); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + testState = true; + setTimeout(() => { + mCountdownController.reset(); + }, 100); + }) + + it('reStartState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.RUNNING); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + setTimeout(() => { + mCountdownController.pause(); + testState = true; + mCountdownController.start(); + }, 100); + }) + + it('reStartStateTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + let testTime = 0; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testTime > 0) { + expect(testTime < totalTimeMs).assertTrue(); + testState = false; + } else if (testState == true) { + testTime = currentTimeMs; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + mCountdownController.pause(); + testState = true; + setTimeout(() => { + mCountdownController.start(); + }, 100); + }) + + it('resetAfterPauseState', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setStateUpdateListener((state) => { + if (testState) { + expect(state).assertEqual(CountdownState.IDLE); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + setTimeout(() => { + mCountdownController.pause(); + testState = true; + mCountdownController.reset(); + }, 100); + }) + + it('resetAfterPauseTime', 0, function () { + let mCountdownController = new CountdownController(); + let testState = false; + mCountdownController.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { + if (testState) { + expect(totalTimeMs).assertEqual(0); + testState = false; + } + }); + mCountdownController.setTime(10000); + mCountdownController.start(); + setTimeout(() => { + mCountdownController.pause(); + testState = true; + mCountdownController.reset(); + }, 100); }) }) } \ No newline at end of file -- Gitee From 5d2704eb147eb5564129f952a291e96ef7239b63 Mon Sep 17 00:00:00 2001 From: liu_gang Date: Fri, 25 Nov 2022 10:17:35 +0800 Subject: [PATCH 11/19] add timer ohosTest Signed-off-by: liu_gang --- .../timer/src/main/ets/controller/TimerController.ets | 11 +++++++++-- product/pc/src/ohosTest/ets/test/Ability.test.ets | 7 +++++++ product/phone/src/ohosTest/ets/test/Ability.test.ets | 6 ++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/feature/timer/src/main/ets/controller/TimerController.ets b/feature/timer/src/main/ets/controller/TimerController.ets index 02ad903..839044e 100644 --- a/feature/timer/src/main/ets/controller/TimerController.ets +++ b/feature/timer/src/main/ets/controller/TimerController.ets @@ -63,6 +63,9 @@ export class TimerController { clearInterval(this.notifierId); this.notifierId = -1; } + if (this.beforePauseTime > 0) { + this.notifyTimeChanges(); + } this.notifierId = setInterval(() => { let timestamp = new Date().getTime(); this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp; @@ -83,7 +86,6 @@ export class TimerController { clearInterval(this.notifierId); this.beforePauseTime += new Date().getTime() - this.startTimestamp; this.currentTimeMs = this.beforePauseTime; - this.notifyTimeChanges(); this.notifierId = -1; this.state = TimerState.PAUSED; if (this.preferences) { @@ -108,7 +110,9 @@ export class TimerController { this.notifyTimeChanges(); this.notifyStateChanges(); this.notifyTimeListChanges(); - this.preferences.clear(); + if (this.preferences) { + this.preferences.clear(); + } } /** @@ -208,6 +212,9 @@ export class TimerController { * Persist preferences */ private flush() { + if (!this.preferences) { + return; + } this.preferences.flush(function (err) { if (err) { console.warn('Failed flush. Cause: ' + err); diff --git a/product/pc/src/ohosTest/ets/test/Ability.test.ets b/product/pc/src/ohosTest/ets/test/Ability.test.ets index 4e443e9..2d4bb4a 100644 --- a/product/pc/src/ohosTest/ets/test/Ability.test.ets +++ b/product/pc/src/ohosTest/ets/test/Ability.test.ets @@ -15,7 +15,10 @@ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' import { TimerController, TimerState } from '@ohos/timer'; +<<<<<<< HEAD import { CountdownController, CountdownState } from '@ohos/countdown'; +======= +>>>>>>> 34e999d (add timer ohosTest) import { TimerUtil } from '@ohos/common'; export default function abilityTest() { @@ -309,6 +312,7 @@ export default function abilityTest() { let res = TimerUtil.timeFormat(num) expect(res).assertEqual(`01:00:00:00.00`) }) +<<<<<<< HEAD }) describe('CountdownTest', function () { @@ -512,5 +516,8 @@ export default function abilityTest() { mCountdownController.reset(); }, 100); }) +======= + +>>>>>>> 34e999d (add timer ohosTest) }) } \ No newline at end of file diff --git a/product/phone/src/ohosTest/ets/test/Ability.test.ets b/product/phone/src/ohosTest/ets/test/Ability.test.ets index e590cc0..7a3e666 100644 --- a/product/phone/src/ohosTest/ets/test/Ability.test.ets +++ b/product/phone/src/ohosTest/ets/test/Ability.test.ets @@ -16,7 +16,10 @@ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' import { TimerController, TimerState } from '@ohos/timer'; import { TimerUtil } from '@ohos/common'; +<<<<<<< HEAD import { CountdownController, CountdownState } from '@ohos/countdown'; +======= +>>>>>>> 34e999d (add timer ohosTest) export default function abilityTest() { describe('ActsAbilityTest', function () { @@ -307,6 +310,7 @@ export default function abilityTest() { let num = 1000 * 60 * 60 * 24 let res = TimerUtil.timeFormat(num) expect(res).assertEqual(`01:00:00:00.00`) +<<<<<<< HEAD }) }) @@ -510,6 +514,8 @@ export default function abilityTest() { testState = true; mCountdownController.reset(); }, 100); +======= +>>>>>>> 34e999d (add timer ohosTest) }) }) } \ No newline at end of file -- Gitee From 6c47313a7a7da44ff8c5190280a3d7764c04b3d8 Mon Sep 17 00:00:00 2001 From: ding_chengjie Date: Fri, 2 Dec 2022 14:21:52 +0800 Subject: [PATCH 12/19] update readme Signed-off-by: ding_chengjie --- README.md => README_zh.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename README.md => README_zh.md (97%) diff --git a/README.md b/README_zh.md similarity index 97% rename from README.md rename to README_zh.md index dd910ba..4d7e39a 100644 --- a/README.md +++ b/README_zh.md @@ -39,4 +39,4 @@ - 语言版本 - eTS - 限制 - - 本示例仅支持标准系统上运行 \ No newline at end of file + - 本示例仅支持标准系统上运行 -- Gitee From b7d40d505ec3a449a290832ec1a14d9c620a8d0e Mon Sep 17 00:00:00 2001 From: ding_chengjie Date: Tue, 6 Dec 2022 09:58:10 +0800 Subject: [PATCH 13/19] add OAT.xml & copyright header Signed-off-by: ding_chengjie --- OAT.xml | 75 +++++++++++++++++++ .../ets/Application/TestAbilityStage.ts | 15 ++++ .../ohosTest/ets/TestAbility/TestAbility.ts | 15 ++++ .../ohosTest/ets/TestAbility/pages/index.ets | 15 ++++ .../ets/TestRunner/OpenHarmonyTestRunner.ts | 15 ++++ .../pc/src/ohosTest/ets/test/List.test.ets | 15 ++++ .../ets/Application/TestAbilityStage.ts | 15 ++++ .../ohosTest/ets/TestAbility/TestAbility.ts | 15 ++++ .../ohosTest/ets/TestAbility/pages/index.ets | 15 ++++ .../ets/TestRunner/OpenHarmonyTestRunner.ts | 15 ++++ .../phone/src/ohosTest/ets/test/List.test.ets | 15 ++++ 11 files changed, 225 insertions(+) create mode 100644 OAT.xml diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 0000000..936afa3 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts b/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts index 2e8d465..e49426a 100644 --- a/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts +++ b/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import AbilityStage from "@ohos.application.AbilityStage" export default class TestAbilityStage extends AbilityStage { diff --git a/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts b/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts index 301aaf6..fa4c507 100644 --- a/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts +++ b/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import Ability from '@ohos.application.Ability' import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' import { Hypium } from '@ohos/hypium' diff --git a/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets b/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets index 733600a..519dd34 100644 --- a/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets +++ b/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import router from '@ohos.router'; @Entry diff --git a/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts b/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts index bdbe7cf..07c9f17 100644 --- a/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts +++ b/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import TestRunner from '@ohos.application.testRunner' import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' diff --git a/product/pc/src/ohosTest/ets/test/List.test.ets b/product/pc/src/ohosTest/ets/test/List.test.ets index d766fe2..80fe72d 100644 --- a/product/pc/src/ohosTest/ets/test/List.test.ets +++ b/product/pc/src/ohosTest/ets/test/List.test.ets @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import abilityTest from './Ability.test' export default function testsuite() { diff --git a/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts b/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts index 2e8d465..e49426a 100644 --- a/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts +++ b/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import AbilityStage from "@ohos.application.AbilityStage" export default class TestAbilityStage extends AbilityStage { diff --git a/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts b/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts index 301aaf6..fa4c507 100644 --- a/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts +++ b/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import Ability from '@ohos.application.Ability' import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' import { Hypium } from '@ohos/hypium' diff --git a/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets b/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets index 733600a..519dd34 100644 --- a/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets +++ b/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import router from '@ohos.router'; @Entry diff --git a/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts b/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts index bdbe7cf..07c9f17 100644 --- a/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts +++ b/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import TestRunner from '@ohos.application.testRunner' import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' diff --git a/product/phone/src/ohosTest/ets/test/List.test.ets b/product/phone/src/ohosTest/ets/test/List.test.ets index d766fe2..80fe72d 100644 --- a/product/phone/src/ohosTest/ets/test/List.test.ets +++ b/product/phone/src/ohosTest/ets/test/List.test.ets @@ -1,3 +1,18 @@ +/** + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import abilityTest from './Ability.test' export default function testsuite() { -- Gitee From 37436f9bddbb2e88370669fedf63ff2b62ac2057 Mon Sep 17 00:00:00 2001 From: shao_junye Date: Tue, 13 Dec 2022 17:47:38 +0800 Subject: [PATCH 14/19] fix select time error problem Signed-off-by: shao_junye --- .../main/ets/controller/CountdownController.ets | 2 +- .../src/main/resources/base/element/string.json | 6 +----- product/pc/src/main/ets/pages/Countdown.ets | 16 ++++++++-------- product/phone/src/main/ets/pages/Countdown.ets | 16 ++++++++-------- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/feature/countdown/src/main/ets/controller/CountdownController.ets b/feature/countdown/src/main/ets/controller/CountdownController.ets index 05e3d3c..11b9d32 100644 --- a/feature/countdown/src/main/ets/controller/CountdownController.ets +++ b/feature/countdown/src/main/ets/controller/CountdownController.ets @@ -239,7 +239,7 @@ export class CountdownController { * Get preferences data. */ public async getPreferences() { - if (this.preferences) { + if (!this.preferences) { this.preferences = await dataStorage.getPreferences(globalThis.abilityContext, this.countdownStr); } } diff --git a/feature/countdown/src/main/resources/base/element/string.json b/feature/countdown/src/main/resources/base/element/string.json index c66d27f..22859d2 100644 --- a/feature/countdown/src/main/resources/base/element/string.json +++ b/feature/countdown/src/main/resources/base/element/string.json @@ -1,9 +1,5 @@ { "string": [ - { - "name": "page_show", - "value": "page from npm package" - }, { "name": "hour", "value": "hour" @@ -14,7 +10,7 @@ }, { "name": "second", - "value": "minute" + "value": "second" } ] } diff --git a/product/pc/src/main/ets/pages/Countdown.ets b/product/pc/src/main/ets/pages/Countdown.ets index bac6986..dbc591d 100644 --- a/product/pc/src/main/ets/pages/Countdown.ets +++ b/product/pc/src/main/ets/pages/Countdown.ets @@ -158,20 +158,20 @@ export struct CountDown { this.controller.setStateUpdateListener((state) => { this.state = state; if (state == CountdownState.STOPPED) { - let date = new Date(this.totalTime); - this.hour = this.fill(date.getHours()); - this.minute = this.fill(date.getMinutes()); - this.second = this.fill(date.getSeconds()); + this.hour = this.fill(Math.floor(this.totalTime / ConfigData.ONE_HOUR_TIME).toString()); + this.minute = this.fill(Math.floor(this.totalTime % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME).toString()); + this.second = this.fill(Math.floor(this.totalTime % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME).toString()); + this.controller.reStart(); } }) this.controller.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { this.currentTime = currentTimeMs; this.totalTime = totalTimeMs; - let date = new Date(this.currentTime); - this.hour = this.fill(date.getHours()); - this.minute = this.fill(date.getMinutes()); - this.second = this.fill(date.getSeconds()); + + this.hour = this.fill(Math.floor(this.currentTime / ConfigData.ONE_HOUR_TIME).toString()); + this.minute = this.fill(Math.floor(this.currentTime % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME).toString()); + this.second = this.fill(Math.floor(this.currentTime % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME).toString()); }) this.controller.getData(); } diff --git a/product/phone/src/main/ets/pages/Countdown.ets b/product/phone/src/main/ets/pages/Countdown.ets index 1cf9584..1bb9eb5 100644 --- a/product/phone/src/main/ets/pages/Countdown.ets +++ b/product/phone/src/main/ets/pages/Countdown.ets @@ -131,20 +131,20 @@ export struct CountDown { this.controller.setStateUpdateListener((state) => { this.state = state; if (state == CountdownState.STOPPED) { - let date = new Date(this.totalTime); - this.hour = this.fill(date.getHours()); - this.minute = this.fill(date.getMinutes()); - this.second = this.fill(date.getSeconds()); + this.hour = this.fill(Math.floor(this.totalTime / ConfigData.ONE_HOUR_TIME).toString()); + this.minute = this.fill(Math.floor(this.totalTime % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME).toString()); + this.second = this.fill(Math.floor(this.totalTime % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME).toString()); + this.controller.reStart(); } }) this.controller.setTimeUpdateListener((currentTimeMs: number, totalTimeMs: number) => { this.currentTime = currentTimeMs; this.totalTime = totalTimeMs; - let date = new Date(this.currentTime); - this.hour = this.fill(date.getHours()); - this.minute = this.fill(date.getMinutes()); - this.second = this.fill(date.getSeconds()); + + this.hour = this.fill(Math.floor(this.currentTime / ConfigData.ONE_HOUR_TIME).toString()); + this.minute = this.fill(Math.floor(this.currentTime % ConfigData.ONE_HOUR_TIME / ConfigData.ONE_MINUTE_TIME).toString()); + this.second = this.fill(Math.floor(this.currentTime % ConfigData.ONE_MINUTE_TIME / ConfigData.ONE_SECOND_TIME).toString()); }) this.controller.getData(); } -- Gitee From 2d297fb56ab94e3bc403cff209e7e6b66d5d0087 Mon Sep 17 00:00:00 2001 From: liu_gang Date: Wed, 11 Jan 2023 15:03:52 +0800 Subject: [PATCH 15/19] amend README_zh.md Signed-off-by: liu_gang --- README_zh.md | 26 +++++++++++++------------- figures/buildHap.png | Bin 0 -> 7069 bytes figures/clock.png | Bin 10250 -> 11248 bytes figures/install.png | Bin 0 -> 10836 bytes figures/signature.png | Bin 0 -> 33935 bytes 5 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 figures/buildHap.png create mode 100644 figures/install.png create mode 100644 figures/signature.png diff --git a/README_zh.md b/README_zh.md index 4d7e39a..42227bc 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,23 +1,17 @@ # 时钟应用 -- [时钟应用](#时钟应用) - - [简介](#简介) - - [目录](#目录) - - [目录结构](#目录结构) - - [约束](#约束) - ## 简介 -时钟应用 可以实现秒表计时功能和倒计时功能。 -时钟应用 采用 扩展的TS语言(eTS)开发,主要的结构如下: +时钟应用可以实现秒表计时功能和倒计时功能。 +时钟应用采用扩展的TS语言(ArkTS)开发,主要的结构如下: ![](./figures/clock.png) - **product** 业务形态层:区分不同产品、不同屏幕的各形态应用,含有个性化业务,组件的配置,以及个性化资源包。 - **feature** - 公共特性层:抽象的公共特性组件集合,可以被各应用形态引用。 + 公共特性层:抽象的公共特性组件集合,可以被各应用形态引用,包含特性对应的UI封装组件和逻辑控制器。 - **common** - 公共能力层:基础能力集,每个应用形态都必须依赖的模块。 + 公共能力层:基础能力集,每个应用形态都必须依赖的模块,包含通用的UI封装组件,工具类和通用的资源包。 ## 目录 ### 目录结构 @@ -26,17 +20,23 @@ ├── common # 公共能力层目录 ├── feature # 公共特性层目录 │ ├── countdown # 倒计时功能目录 -│ │ └── components # 倒计时组件目录 +│ │ └── components # 倒计时UI封装组件目录 │ │ └── controller # 倒计时控制逻辑目录 │ └── timer # 秒表功能目录 -│ └── components # 秒表组件目录 +│ └── components # 秒表UI封装组件目录 │ └── controller # 秒表控制逻辑目录 ├── product # 业务形态层目录 ``` +## 安装 +对应用完成签名,打包后,使用`hdc_std install "hap包地址"`命令进行安装 +![](./figures/signature.png) +![](./figures/buildHap.png) +![](./figures/install.png) + ## 约束 - 开发环境 - **DevEco Studio for OpenHarmony**: 版本号大于3.0.0.992,下载安装OpenHarmony SDK API Version 9。(初始的IDE配置可以参考IDE的使用文档) - 语言版本 - - eTS + - ArkTS - 限制 - 本示例仅支持标准系统上运行 diff --git a/figures/buildHap.png b/figures/buildHap.png new file mode 100644 index 0000000000000000000000000000000000000000..ac1efd04fd24c0ab58303fe0e17aad0d45faf7db GIT binary patch literal 7069 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 z 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 S8xY-niHf4;z2dtMpZ_0y-5nnQ literal 0 HcmV?d00001 -- Gitee From 03da6e5b79615ed44c5ce138f9dffbe1dca5f3b0 Mon Sep 17 00:00:00 2001 From: liu_gang Date: Wed, 11 Jan 2023 16:01:34 +0800 Subject: [PATCH 16/19] modify OAT.xml Signed-off-by: liu_gang --- OAT.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OAT.xml b/OAT.xml index 936afa3..db85049 100644 --- a/OAT.xml +++ b/OAT.xml @@ -29,6 +29,18 @@ desc="组件效果图,无需修改" name="figures/clock.png" type="filepath"/> + + + Date: Fri, 24 Feb 2023 10:41:31 +0800 Subject: [PATCH 17/19] modify the copyrights Signed-off-by: ding_chengjie --- .gitignore | 3 ++- common/index.ets | 2 +- common/src/main/ets/components/imageComponent.ets | 2 +- common/src/main/ets/utils/ConfigData.ets | 2 +- common/src/main/ets/utils/LogUtil.ts | 2 +- common/src/main/ets/utils/TimerUtil.ets | 2 +- feature/countdown/index.ets | 2 +- feature/countdown/src/main/ets/components/CountdownView.ets | 2 +- feature/countdown/src/main/ets/components/TimeSelectView.ets | 2 +- .../countdown/src/main/ets/controller/CountdownController.ets | 2 +- feature/timer/index.ets | 2 +- feature/timer/src/main/ets/components/TimerView.ets | 2 +- feature/timer/src/main/ets/controller/TimerController.ets | 2 +- product/pc/src/main/ets/Application/MyAbilityStage.ts | 2 +- product/pc/src/main/ets/MainAbility/MainAbility.ts | 2 +- product/pc/src/main/ets/pages/Countdown.ets | 2 +- product/pc/src/main/ets/pages/index.ets | 2 +- product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets | 2 +- product/pc/src/main/ets/pages/timer/TimeOfRecord.ets | 2 +- product/pc/src/main/ets/pages/timer/Timer.ets | 2 +- product/pc/src/main/ets/pages/timer/TimerClock.ets | 2 +- product/pc/src/main/ets/pages/timer/TimerControl.ets | 2 +- product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts | 2 +- product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts | 2 +- product/pc/src/ohosTest/ets/TestAbility/pages/index.ets | 2 +- .../pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts | 2 +- product/pc/src/ohosTest/ets/test/Ability.test.ets | 2 +- product/pc/src/ohosTest/ets/test/List.test.ets | 2 +- product/phone/src/main/ets/Application/MyAbilityStage.ts | 2 +- product/phone/src/main/ets/MainAbility/MainAbility.ts | 2 +- product/phone/src/main/ets/pages/Countdown.ets | 2 +- product/phone/src/main/ets/pages/index.ets | 2 +- product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets | 2 +- product/phone/src/main/ets/pages/timer/TimeOfRecord.ets | 2 +- product/phone/src/main/ets/pages/timer/Timer.ets | 2 +- product/phone/src/main/ets/pages/timer/TimerClock.ets | 2 +- product/phone/src/main/ets/pages/timer/TimerControl.ets | 2 +- product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts | 2 +- product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts | 2 +- product/phone/src/ohosTest/ets/TestAbility/pages/index.ets | 2 +- .../phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts | 2 +- product/phone/src/ohosTest/ets/test/Ability.test.ets | 2 +- product/phone/src/ohosTest/ets/test/List.test.ets | 2 +- 43 files changed, 44 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index 646ca11..f8ce57b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ **/build /.hvigor .preview -*/.preview \ No newline at end of file +*/.preview +**/package-lock.json \ No newline at end of file diff --git a/common/index.ets b/common/index.ets index 0f23c87..cde2092 100644 --- a/common/index.ets +++ b/common/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/common/src/main/ets/components/imageComponent.ets b/common/src/main/ets/components/imageComponent.ets index ee1fbf6..38f95cb 100644 --- a/common/src/main/ets/components/imageComponent.ets +++ b/common/src/main/ets/components/imageComponent.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/common/src/main/ets/utils/ConfigData.ets b/common/src/main/ets/utils/ConfigData.ets index 95247ff..046b180 100644 --- a/common/src/main/ets/utils/ConfigData.ets +++ b/common/src/main/ets/utils/ConfigData.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/common/src/main/ets/utils/LogUtil.ts b/common/src/main/ets/utils/LogUtil.ts index 831a269..e320097 100644 --- a/common/src/main/ets/utils/LogUtil.ts +++ b/common/src/main/ets/utils/LogUtil.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/common/src/main/ets/utils/TimerUtil.ets b/common/src/main/ets/utils/TimerUtil.ets index 5a24ee2..34c2fb3 100644 --- a/common/src/main/ets/utils/TimerUtil.ets +++ b/common/src/main/ets/utils/TimerUtil.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/feature/countdown/index.ets b/feature/countdown/index.ets index e6f2316..5327a82 100644 --- a/feature/countdown/index.ets +++ b/feature/countdown/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/feature/countdown/src/main/ets/components/CountdownView.ets b/feature/countdown/src/main/ets/components/CountdownView.ets index bb40a77..7f51b62 100644 --- a/feature/countdown/src/main/ets/components/CountdownView.ets +++ b/feature/countdown/src/main/ets/components/CountdownView.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/feature/countdown/src/main/ets/components/TimeSelectView.ets b/feature/countdown/src/main/ets/components/TimeSelectView.ets index 65075a3..5162ad5 100644 --- a/feature/countdown/src/main/ets/components/TimeSelectView.ets +++ b/feature/countdown/src/main/ets/components/TimeSelectView.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/feature/countdown/src/main/ets/controller/CountdownController.ets b/feature/countdown/src/main/ets/controller/CountdownController.ets index 11b9d32..d54767c 100644 --- a/feature/countdown/src/main/ets/controller/CountdownController.ets +++ b/feature/countdown/src/main/ets/controller/CountdownController.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/feature/timer/index.ets b/feature/timer/index.ets index 0f2258b..e628e7f 100644 --- a/feature/timer/index.ets +++ b/feature/timer/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/feature/timer/src/main/ets/components/TimerView.ets b/feature/timer/src/main/ets/components/TimerView.ets index 9707774..0b5760e 100644 --- a/feature/timer/src/main/ets/components/TimerView.ets +++ b/feature/timer/src/main/ets/components/TimerView.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/feature/timer/src/main/ets/controller/TimerController.ets b/feature/timer/src/main/ets/controller/TimerController.ets index 839044e..b5c5ba2 100644 --- a/feature/timer/src/main/ets/controller/TimerController.ets +++ b/feature/timer/src/main/ets/controller/TimerController.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/Application/MyAbilityStage.ts b/product/pc/src/main/ets/Application/MyAbilityStage.ts index b3f3c30..0a9efc1 100644 --- a/product/pc/src/main/ets/Application/MyAbilityStage.ts +++ b/product/pc/src/main/ets/Application/MyAbilityStage.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/MainAbility/MainAbility.ts b/product/pc/src/main/ets/MainAbility/MainAbility.ts index 5b86040..ae6097e 100644 --- a/product/pc/src/main/ets/MainAbility/MainAbility.ts +++ b/product/pc/src/main/ets/MainAbility/MainAbility.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/pages/Countdown.ets b/product/pc/src/main/ets/pages/Countdown.ets index dbc591d..7fea84f 100644 --- a/product/pc/src/main/ets/pages/Countdown.ets +++ b/product/pc/src/main/ets/pages/Countdown.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/pages/index.ets b/product/pc/src/main/ets/pages/index.ets index 953b9e7..8d7b21b 100644 --- a/product/pc/src/main/ets/pages/index.ets +++ b/product/pc/src/main/ets/pages/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets index d032a41..a9c99d5 100644 --- a/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/pc/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets index c14fe73..70d9439 100644 --- a/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/pc/src/main/ets/pages/timer/TimeOfRecord.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/pages/timer/Timer.ets b/product/pc/src/main/ets/pages/timer/Timer.ets index 022c89b..2a61730 100644 --- a/product/pc/src/main/ets/pages/timer/Timer.ets +++ b/product/pc/src/main/ets/pages/timer/Timer.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/pages/timer/TimerClock.ets b/product/pc/src/main/ets/pages/timer/TimerClock.ets index 61cf2f4..5e8f75d 100644 --- a/product/pc/src/main/ets/pages/timer/TimerClock.ets +++ b/product/pc/src/main/ets/pages/timer/TimerClock.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/main/ets/pages/timer/TimerControl.ets b/product/pc/src/main/ets/pages/timer/TimerControl.ets index 90cae72..0a84a5c 100644 --- a/product/pc/src/main/ets/pages/timer/TimerControl.ets +++ b/product/pc/src/main/ets/pages/timer/TimerControl.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts b/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts index e49426a..23d6aa9 100644 --- a/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts +++ b/product/pc/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts b/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts index fa4c507..9bb3e67 100644 --- a/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts +++ b/product/pc/src/ohosTest/ets/TestAbility/TestAbility.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets b/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets index 519dd34..b95547c 100644 --- a/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets +++ b/product/pc/src/ohosTest/ets/TestAbility/pages/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts b/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts index 07c9f17..e82df7a 100644 --- a/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts +++ b/product/pc/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/ohosTest/ets/test/Ability.test.ets b/product/pc/src/ohosTest/ets/test/Ability.test.ets index 2d4bb4a..05f3a3d 100644 --- a/product/pc/src/ohosTest/ets/test/Ability.test.ets +++ b/product/pc/src/ohosTest/ets/test/Ability.test.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/pc/src/ohosTest/ets/test/List.test.ets b/product/pc/src/ohosTest/ets/test/List.test.ets index 80fe72d..a75fa4e 100644 --- a/product/pc/src/ohosTest/ets/test/List.test.ets +++ b/product/pc/src/ohosTest/ets/test/List.test.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/Application/MyAbilityStage.ts b/product/phone/src/main/ets/Application/MyAbilityStage.ts index b3f3c30..0a9efc1 100644 --- a/product/phone/src/main/ets/Application/MyAbilityStage.ts +++ b/product/phone/src/main/ets/Application/MyAbilityStage.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/MainAbility/MainAbility.ts b/product/phone/src/main/ets/MainAbility/MainAbility.ts index 5b86040..ae6097e 100644 --- a/product/phone/src/main/ets/MainAbility/MainAbility.ts +++ b/product/phone/src/main/ets/MainAbility/MainAbility.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/pages/Countdown.ets b/product/phone/src/main/ets/pages/Countdown.ets index 1bb9eb5..327a450 100644 --- a/product/phone/src/main/ets/pages/Countdown.ets +++ b/product/phone/src/main/ets/pages/Countdown.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/pages/index.ets b/product/phone/src/main/ets/pages/index.ets index 832bed1..89e915d 100644 --- a/product/phone/src/main/ets/pages/index.ets +++ b/product/phone/src/main/ets/pages/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets index 7cd031e..dd13b6d 100644 --- a/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets +++ b/product/phone/src/main/ets/pages/timer/CurrentTimeDisplay.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets index fa157dc..206318d 100644 --- a/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets +++ b/product/phone/src/main/ets/pages/timer/TimeOfRecord.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/pages/timer/Timer.ets b/product/phone/src/main/ets/pages/timer/Timer.ets index d6d68f2..1fc4261 100644 --- a/product/phone/src/main/ets/pages/timer/Timer.ets +++ b/product/phone/src/main/ets/pages/timer/Timer.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/pages/timer/TimerClock.ets b/product/phone/src/main/ets/pages/timer/TimerClock.ets index a0d0a6b..b66502c 100644 --- a/product/phone/src/main/ets/pages/timer/TimerClock.ets +++ b/product/phone/src/main/ets/pages/timer/TimerClock.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/main/ets/pages/timer/TimerControl.ets b/product/phone/src/main/ets/pages/timer/TimerControl.ets index 8cc9c80..2194ff7 100644 --- a/product/phone/src/main/ets/pages/timer/TimerControl.ets +++ b/product/phone/src/main/ets/pages/timer/TimerControl.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts b/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts index e49426a..23d6aa9 100644 --- a/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts +++ b/product/phone/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts b/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts index fa4c507..9bb3e67 100644 --- a/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts +++ b/product/phone/src/ohosTest/ets/TestAbility/TestAbility.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets b/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets index 519dd34..b95547c 100644 --- a/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets +++ b/product/phone/src/ohosTest/ets/TestAbility/pages/index.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts b/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts index 07c9f17..e82df7a 100644 --- a/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts +++ b/product/phone/src/ohosTest/ets/TestRunner/OpenHarmonyTestRunner.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/ohosTest/ets/test/Ability.test.ets b/product/phone/src/ohosTest/ets/test/Ability.test.ets index 7a3e666..6c7475a 100644 --- a/product/phone/src/ohosTest/ets/test/Ability.test.ets +++ b/product/phone/src/ohosTest/ets/test/Ability.test.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/product/phone/src/ohosTest/ets/test/List.test.ets b/product/phone/src/ohosTest/ets/test/List.test.ets index 80fe72d..a75fa4e 100644 --- a/product/phone/src/ohosTest/ets/test/List.test.ets +++ b/product/phone/src/ohosTest/ets/test/List.test.ets @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022 HiHope Open Source Organization. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at -- Gitee From 502ba3996fb6d5dcf131483f624b4a1b6cc66d5a Mon Sep 17 00:00:00 2001 From: ding_chengjie Date: Fri, 24 Feb 2023 17:25:51 +0800 Subject: [PATCH 18/19] update OAT.xml Signed-off-by: ding_chengjie --- OAT.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OAT.xml b/OAT.xml index db85049..b51eb3d 100644 --- a/OAT.xml +++ b/OAT.xml @@ -81,7 +81,12 @@ desc="hvigor配置文件,DevEco Studio自动生成,不手动修改" name="*.json5.ftl" type="filename"/> - + + + + + + \ No newline at end of file -- Gitee From f10590c22b3438848c43de9bb130905c23f1f4e2 Mon Sep 17 00:00:00 2001 From: ding_chengjie Date: Mon, 20 Mar 2023 10:45:22 +0800 Subject: [PATCH 19/19] format the OAT.xml Signed-off-by: ding_chengjie --- OAT.xml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/OAT.xml b/OAT.xml index b51eb3d..10e6728 100644 --- a/OAT.xml +++ b/OAT.xml @@ -81,11 +81,20 @@ desc="hvigor配置文件,DevEco Studio自动生成,不手动修改" name="*.json5.ftl" type="filename"/> - + - - - + + + -- Gitee