From a364b709f200a5789c998fca3bd0a8022f074975 Mon Sep 17 00:00:00 2001 From: sunlian Date: Mon, 20 May 2024 15:53:50 +0800 Subject: [PATCH] music player online project Signed-off-by: sunlian --- README.md | 13 + docs/FeatureMapRule.md | 3 + scenario/MusicPlayerOnline/.gitignore | 11 + scenario/MusicPlayerOnline/AppScope/app.json5 | 10 + .../resources/base/element/string.json | 8 + .../resources/base/media/app_icon.png | Bin 0 -> 2041 bytes scenario/MusicPlayerOnline/README_zh.md | 153 ++++++++ .../MusicPlayerOnline/build-profile.json5 | 49 +++ scenario/MusicPlayerOnline/entry/.gitignore | 6 + .../entry/build-profile.json5 | 31 ++ .../MusicPlayerOnline/entry/hvigorfile.ts | 6 + .../entry/obfuscation-rules.txt | 18 + .../MusicPlayerOnline/entry/oh-package.json5 | 10 + .../main/ets/entryability/EntryAbility.ets | 56 +++ .../src/main/ets/manager/PlayerManager.ets | 301 +++++++++++++++ .../src/main/ets/manager/ServerConstants.ets | 54 +++ .../entry/src/main/ets/model/AudioItem.ets | 31 ++ .../entry/src/main/ets/model/LrcLine.ets | 28 ++ .../entry/src/main/ets/model/PlayListData.ets | 43 +++ .../entry/src/main/ets/pages/Index.ets | 214 ++++++++++ .../entry/src/main/ets/utils/CommonUtils.ets | 61 +++ .../entry/src/main/ets/utils/Logger.ts | 45 +++ .../entry/src/main/ets/view/PlayList.ets | 73 ++++ .../entry/src/main/ets/view/PlayListItem.ets | 75 ++++ .../entry/src/main/ets/view/PlayerBar.ets | 152 ++++++++ .../entry/src/main/ets/view/PlayerDetail.ets | 365 ++++++++++++++++++ .../entry/src/main/ets/view/SongCell.ets | 43 +++ .../entry/src/main/module.json5 | 63 +++ .../main/resources/base/element/color.json | 8 + .../main/resources/base/element/string.json | 20 + .../base/media/ic_public_arrow_down_0.png | Bin 0 -> 287 bytes .../base/media/ic_public_arrow_right.png | Bin 0 -> 275 bytes .../base/media/ic_public_arrow_right_grey.png | Bin 0 -> 240 bytes .../base/media/ic_public_comments.png | Bin 0 -> 492 bytes .../resources/base/media/ic_public_favor.png | Bin 0 -> 899 bytes .../base/media/ic_public_list_cycle.png | Bin 0 -> 414 bytes .../resources/base/media/ic_public_pause.png | Bin 0 -> 202 bytes .../resources/base/media/ic_public_play.png | Bin 0 -> 345 bytes .../base/media/ic_public_play_last.png | Bin 0 -> 320 bytes .../base/media/ic_public_play_next.png | Bin 0 -> 342 bytes .../base/media/ic_public_play_white.png | Bin 0 -> 365 bytes .../resources/base/media/ic_public_share.png | Bin 0 -> 448 bytes .../base/media/ic_public_view_list.png | Bin 0 -> 232 bytes .../base/media/ic_screenshot_line.png | Bin 0 -> 143 bytes .../base/media/ic_screenshot_line_select.png | Bin 0 -> 144 bytes .../src/main/resources/base/media/icon.png | Bin 0 -> 2041 bytes .../main/resources/base/media/startIcon.png | Bin 0 -> 4351 bytes .../resources/base/profile/main_pages.json | 5 + .../main/resources/en_US/element/string.json | 16 + .../main/resources/zh_CN/element/string.json | 16 + .../entry/src/mock/mock-config.json5 | 2 + .../src/ohosTest/ets/test/Ability.test.ets | 50 +++ .../entry/src/ohosTest/ets/test/List.test.ets | 20 + .../ohosTest/ets/testability/TestAbility.ets | 64 +++ .../ohosTest/ets/testability/pages/Index.ets | 17 + .../ets/testrunner/OpenHarmonyTestRunner.ets | 107 +++++ .../entry/src/ohosTest/module.json5 | 37 ++ .../resources/base/element/color.json | 8 + .../resources/base/element/string.json | 16 + .../ohosTest/resources/base/media/icon.png | Bin 0 -> 2041 bytes .../resources/base/profile/test_pages.json | 5 + .../entry/src/test/List.test.ets | 20 + .../entry/src/test/LocalUnit.test.ets | 48 +++ .../hvigor/hvigor-config.json5 | 22 ++ .../hvigor/hvigor-wrapper.js | 1 + scenario/MusicPlayerOnline/hvigorfile.ts | 6 + scenario/MusicPlayerOnline/hvigorw | 54 +++ scenario/MusicPlayerOnline/hvigorw.bat | 54 +++ .../MusicPlayerOnline/oh-package-lock.json5 | 21 + scenario/MusicPlayerOnline/oh-package.json5 | 14 + .../MusicPlayerOnline/screenshots/detail.jpeg | Bin 0 -> 41331 bytes .../MusicPlayerOnline/screenshots/home.jpeg | Bin 0 -> 41994 bytes .../screenshots/playlist.jpeg | Bin 0 -> 60613 bytes scenario/MyMusic/build-profile.json5 | 10 +- scenario/MyMusic/hvigor/hvigor-config.json5 | 6 +- scenario/MyMusic/oh-package-lock.json5 | 6 +- 76 files changed, 2565 insertions(+), 10 deletions(-) create mode 100644 scenario/MusicPlayerOnline/.gitignore create mode 100644 scenario/MusicPlayerOnline/AppScope/app.json5 create mode 100644 scenario/MusicPlayerOnline/AppScope/resources/base/element/string.json create mode 100644 scenario/MusicPlayerOnline/AppScope/resources/base/media/app_icon.png create mode 100644 scenario/MusicPlayerOnline/README_zh.md create mode 100644 scenario/MusicPlayerOnline/build-profile.json5 create mode 100644 scenario/MusicPlayerOnline/entry/.gitignore create mode 100644 scenario/MusicPlayerOnline/entry/build-profile.json5 create mode 100644 scenario/MusicPlayerOnline/entry/hvigorfile.ts create mode 100644 scenario/MusicPlayerOnline/entry/obfuscation-rules.txt create mode 100644 scenario/MusicPlayerOnline/entry/oh-package.json5 create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/entryability/EntryAbility.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/manager/PlayerManager.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/manager/ServerConstants.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/model/AudioItem.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/model/LrcLine.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/model/PlayListData.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/pages/Index.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/utils/CommonUtils.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/utils/Logger.ts create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayList.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayListItem.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerBar.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerDetail.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/ets/view/SongCell.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/main/module.json5 create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/element/color.json create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/element/string.json create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_arrow_down_0.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_arrow_right.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_arrow_right_grey.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_comments.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_favor.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_list_cycle.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_pause.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play_last.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play_next.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play_white.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_share.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_view_list.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_screenshot_line.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_screenshot_line_select.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/icon.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/media/startIcon.png create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/base/profile/main_pages.json create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/en_US/element/string.json create mode 100644 scenario/MusicPlayerOnline/entry/src/main/resources/zh_CN/element/string.json create mode 100644 scenario/MusicPlayerOnline/entry/src/mock/mock-config.json5 create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/Ability.test.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/List.test.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/TestAbility.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/pages/Index.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/module.json5 create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/color.json create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/string.json create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/media/icon.png create mode 100644 scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/profile/test_pages.json create mode 100644 scenario/MusicPlayerOnline/entry/src/test/List.test.ets create mode 100644 scenario/MusicPlayerOnline/entry/src/test/LocalUnit.test.ets create mode 100644 scenario/MusicPlayerOnline/hvigor/hvigor-config.json5 create mode 100644 scenario/MusicPlayerOnline/hvigor/hvigor-wrapper.js create mode 100644 scenario/MusicPlayerOnline/hvigorfile.ts create mode 100644 scenario/MusicPlayerOnline/hvigorw create mode 100644 scenario/MusicPlayerOnline/hvigorw.bat create mode 100644 scenario/MusicPlayerOnline/oh-package-lock.json5 create mode 100644 scenario/MusicPlayerOnline/oh-package.json5 create mode 100644 scenario/MusicPlayerOnline/screenshots/detail.jpeg create mode 100644 scenario/MusicPlayerOnline/screenshots/home.jpeg create mode 100644 scenario/MusicPlayerOnline/screenshots/playlist.jpeg diff --git a/README.md b/README.md index df99bfc2..28532d0d 100644 --- a/README.md +++ b/README.md @@ -226,6 +226,19 @@ ``` { "description": "Configuration for myMusic Tests", + { + "description": "Configuration for myshopping Tests", + "level": ["0","1","2"], + "type": "function", + "component": "player_framework", + "syscap": [ + "SystemCapability.Multimedia.Media.AudioPlayer", + "SystemCapability.Multimedia.Media.VideoPlayer", + "SystemCapability.Multimedia.Media.AudioRecorder", + "SystemCapability.Multimedia.Media.VideoRecorder", + "SystemCapability.Multimedia.Media.AVPlayer", + "SystemCapability.Multimedia.Media.AVRecorder" + ], "driver": { "type": "OHJSUnitTest", "test-timeout": "180000", diff --git a/docs/FeatureMapRule.md b/docs/FeatureMapRule.md index 510a3f4f..6d769ec2 100644 --- a/docs/FeatureMapRule.md +++ b/docs/FeatureMapRule.md @@ -52,6 +52,9 @@ lv0_function_playerFramework_mediaAudioPlayer_001 编写执行配置文件:testcases/xxx.json 填写用例级别、分类、模块。 + +syscap非必填。 + ``` { "description": "Configuration for myshopping Tests", diff --git a/scenario/MusicPlayerOnline/.gitignore b/scenario/MusicPlayerOnline/.gitignore new file mode 100644 index 00000000..fbabf771 --- /dev/null +++ b/scenario/MusicPlayerOnline/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/AppScope/app.json5 b/scenario/MusicPlayerOnline/AppScope/app.json5 new file mode 100644 index 00000000..9f09d6f2 --- /dev/null +++ b/scenario/MusicPlayerOnline/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.musicPlayerOnline", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/scenario/MusicPlayerOnline/AppScope/resources/base/element/string.json b/scenario/MusicPlayerOnline/AppScope/resources/base/element/string.json new file mode 100644 index 00000000..75328bdd --- /dev/null +++ b/scenario/MusicPlayerOnline/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "musicPlayerOnline" + } + ] +} diff --git a/scenario/MusicPlayerOnline/AppScope/resources/base/media/app_icon.png b/scenario/MusicPlayerOnline/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd45accb1dfd2fd0da16c732c72faa6e46b26521 GIT binary patch literal 2041 zcmaJ?c~nzZ9u6@;0AXaYAVN(;Kr(@>EJ+}skOWf=BA~*l4us@ELY9{%0m5QX6pnb} z(jZF|S&pLAS}3BZAfeQSvJ_h>F2Q1PYqi?o5`;m_yjZdG$1v}l_wK#F^L^iMz2}uD z#K$>1dON~kFlWvhW+Jp=tuN9J`ZlM-rl4h+ij|^D0y9;4JOuz-EdVnB6i3R-0ulk9 zApi4zAQA>!N9@-o026$1@L`d124`3G5<@_m`0f)Ug_Ie~;HT2q<_a=HH> zDwTdfD^-cW-|_xWVP$f@93UhDN-#&khZ>jZXLTi~$0`7x3REP6pk%&^2|`c>DutjN zMJD4Zs6Z}{FOpd;*mo2zm(GzXRXiCV;4m3zNCYnu3Fy=i5;2An&Lp!#LP;bRD~1&s z%VH6UY+}r6YDgG+p34OJIZ{BTn&%4s=CT&#TBkuOhdeU@g(w#guoa*b^)73=XyI65 z7Swys6)YS}?1EeZ6b!-I+yCnIya^g0>-NLsLWd8t56GZ_S3r|ZGbR+mV2ErEb9J)X zIF!njY-D-7{qtF2(?nlQ$0}!pzt=}hc*m%%)0Jb#N_K4@IC-`Pi5DahPZN7N9rH;ol;Gc*>-Go@gXKTM{eP)iJj6CYTIi}B#zLKZYD@_;m zrXmXXsFq@~ou-z!9bHoM8*(hwl>X(zm)TDcdkF4lZm$1jP*HbnD`o1$g}_R#+bu2D zr%7Y8KdsaC-V*aem5#@*M%r^GPgu%P2e-BnBClhP2yoGFe40>);=}>{NONtkXQ01p z)OX^t2Ojhddot9eg0WTIVSTNBa}7V-^_pO595w|Hx9q?k4dMp@$G7PK*TD=y;ck6J zdGRB!_RAI2nR3%tO1IkdWp*bw*?<=pM_LZb30?!oK)s;En( z!#nnd9=cXJ<}+e{XLdx(q3&ikJISe?eSHHohk+pz+$6Cv{ytvc{QXmMn2XQ9U8rvt zrJdAn(0gpSD@N=yTrI_2^P#*zQg7MTp1)k(lv(*(KtUR6@M|2WB>2wRwC-h=wk6XF zPtSes*_JwI+^d>xW489MJw5R6=t5?{R zc|E8i?RL@p9)A3ZJAQOg`}+F;<_vnWA!KxR#g%jZ@y_1Qu#Uw)kFPw_xmZ?a^e*1{ zM|ImtqA|(CaDQ@Fyvcof`MN66&VI6m6gAyAXx`%cDx6BI{Bj#}V*Rn1(b~;Am)D2u zX7(027IO?Z2VYK^1vXXpoZ@AtH~N?0rYWwtyA15`6vEf6fk&;o-L;7zFt`5nk*iOy z`<918zB+k;EytI$FAXug)jk*e@e};4e9g__w4A5ev!!)H$yC@{?vsRqJ##X1R%xPG z&_R3oDi$MtTkVqfPj)HEUDx_7wd!y{8#1%$U*Dd0sK@=#6+!XlsE-s^1f5E`R9Wo71^b~mbVdU;Fw0LG~mUQg;xsX4QYRo3B@rH_=ry>DE8ef!c2ta8UcI#26# zF|`*4wtMHe@%#eGZw`#Yj|QWuB`eRD)b~)r9mM95p_JVG%-IdcbIX5qG#GpGD+IrS zEqxb1Rg&Dadk5#7t4j68I1f!@A$efp1?I%&d*56)yl!tkz!14<$0Od_&6cGw$WW0r zjSlQA7l*6;vgfhv!cR|RmAD$+w6j`rVf=-?-D@q>kOseUVSb*~jbAS^*1h?ZL)n(9 zDa}`4etXO6`}9;{k5E^N{rcfnV_(LPwsDg``wtyS*V<19c3!PGJ3Kqy9ksvkwbJ%Z z*N(fT0{e*Wji-Ck5!3YE0j|PZ@&z`v=kitWL$bqSt!e4bH!+(|Q)CZ30^nVPfkx{s zX{6of`p=BiPb@u@IyL!tRk>?qgBqCmo-Zlt!636g?z`s~zdfwuB7DXZHvV`Usp+%Z zo*&;Biu@MHE&2j+?j^o`Cr12u<>vOe=a&8a2hlcmFjJiDR>XnD4c4DAhZWCkiAgW{ E51q9-lK=n! literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/README_zh.md b/scenario/MusicPlayerOnline/README_zh.md new file mode 100644 index 00000000..bb82fa2d --- /dev/null +++ b/scenario/MusicPlayerOnline/README_zh.md @@ -0,0 +1,153 @@ +# 我的音乐 + +### 介绍 + +本示例主要实现网络音乐展示和播放,以此测试OpenHarmony是否支持网络信息获取,网络流媒体播放,以及是否存在问题。 + +测试设计及实现方法: + + 1.参考网络音乐应用内容,设计应用的功能、数据、测试用例 + + 2.开发应用功能,展示功能和数据内容 + + 3.开发测试用例,检查应用功能及数据内容 + + 4.测试方式: + 1)运行应用手工测试,检查应用是否正确运行及内容是否正确 + 2)通过DevEco 测试框架自动化执行测试套并查看结果和测试log + +### 效果预览 + +| 主页 | 播客 | 我的 | +|---------------------------------|-----------------------------------|-------------------------------------| +| ![image](screenshots/home.jpeg) | ![image](screenshots/detail.jpeg) | ![image](screenshots/playlist.jpeg) | + + +### 工程目录 + +``` +├─main +│ │ module.json5 +│ │ +│ ├─ets +│ │ ├─entryability +│ │ │ EntryAbility.ets +│ │ │ +│ │ ├─manager +│ │ │ PlayerManager.ets +│ │ │ ServerConstants.ets +│ │ │ +│ │ ├─model +│ │ │ AudioItem.ets +│ │ │ LrcLine.ets +│ │ │ PlayListData.ets +│ │ │ +│ │ ├─pages +│ │ │ Index.ets +│ │ │ +│ │ ├─utils +│ │ │ CommonUtils.ets +│ │ │ Logger.ts +│ │ │ +│ │ └─view +│ │ PlayerBar.ets +│ │ PlayerDetail.ets +│ │ PlayList.ets +│ │ PlayListItem.ets +│ │ SongCell.ets +│ │ +│ └─resources +│ ├─base +│ │ ├─element +│ │ │ color.json +│ │ │ string.json +│ │ │ +│ │ ├─media +│ │ │ icon.png +│ │ │ ic_public_arrow_down_0.png +│ │ │ ic_public_arrow_right.png +│ │ │ ic_public_arrow_right_grey.png +│ │ │ ic_public_comments.png +│ │ │ ic_public_favor.png +│ │ │ ic_public_list_cycle.png +│ │ │ ic_public_pause.png +│ │ │ ic_public_play.png +│ │ │ ic_public_play_last.png +│ │ │ ic_public_play_next.png +│ │ │ ic_public_play_white.png +│ │ │ ic_public_share.png +│ │ │ ic_public_view_list.png +│ │ │ ic_screenshot_line.png +│ │ │ ic_screenshot_line_select.png +│ │ │ startIcon.png +│ │ │ +│ │ └─profile +│ │ main_pages.json +│ │ +│ ├─en_US +│ │ └─element +│ │ string.json +│ │ +│ ├─rawfile +│ └─zh_CN +│ └─element +│ string.json +│ +├─mock +│ mock-config.json5 +│ +├─ohosTest +│ │ module.json5 +│ │ +│ ├─ets +│ │ ├─test +│ │ │ Ability.test.ets +│ │ │ List.test.ets +│ │ │ +│ │ ├─testability +│ │ │ │ TestAbility.ets +│ │ │ │ +│ │ │ └─pages +│ │ │ Index.ets +│ │ │ +│ │ └─testrunner +│ │ OpenHarmonyTestRunner.ets +│ │ +│ └─resources +│ └─base +│ ├─element +│ │ color.json +│ │ string.json +│ │ +│ ├─media +│ │ icon.png +│ │ +│ └─profile +│ test_pages.json +│ +└─test + List.test.ets + LocalUnit.test.ets + +``` + +### 相关权限 +无 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:RK3568; +2. 本示例仅支持API11版本SDK,版本号:4.1.7.5; +3. 本示例需要使用DevEco Studio 4.1 Release (Build Version: 4.0.0.400); + +### 下载 + +如需单独下载本工程,执行如下命令: + +``` +git init +git config core.sparsecheckout true +echo scenario/MusicPlayerOnline/ > .git/info/sparse-checkout +git remote add origin https://gitee.com/openharmony-sig/ostest_integration_test.git +git pull origin master +``` \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/build-profile.json5 b/scenario/MusicPlayerOnline/build-profile.json5 new file mode 100644 index 00000000..2767ef92 --- /dev/null +++ b/scenario/MusicPlayerOnline/build-profile.json5 @@ -0,0 +1,49 @@ +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:/Users/Administrator/.ohos/config/openharmony/default_MusicPlayerOnline_FXYBOAf69SUjZDCrDt8Xwf1b9BjvpsV8G8MXGjUFiRw=.cer", + "storePassword": "0000001BDDA9B8D36C2A9429D4688C460B0ED52F4CFB3E952032497A3BDE2E6651EA0688193DE9CCB4B4CD", + "keyAlias": "debugKey", + "keyPassword": "0000001B1EACADFF14787367B5F4314733915F814C676FE175A16E37C9CD5D77A08128141265D73FEDAD48", + "profile": "C:/Users/Administrator/.ohos/config/openharmony/default_MusicPlayerOnline_FXYBOAf69SUjZDCrDt8Xwf1b9BjvpsV8G8MXGjUFiRw=.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:/Users/Administrator/.ohos/config/openharmony/default_MusicPlayerOnline_FXYBOAf69SUjZDCrDt8Xwf1b9BjvpsV8G8MXGjUFiRw=.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": 11, + "compatibleSdkVersion": 11, + "runtimeOS": "OpenHarmony" + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/.gitignore b/scenario/MusicPlayerOnline/entry/.gitignore new file mode 100644 index 00000000..e2713a27 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/build-profile.json5 b/scenario/MusicPlayerOnline/entry/build-profile.json5 new file mode 100644 index 00000000..197e83c1 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/build-profile.json5 @@ -0,0 +1,31 @@ +{ + "apiType": "stageMode", + "buildOption": { + "arkOptions": { + // "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */ + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/hvigorfile.ts b/scenario/MusicPlayerOnline/entry/hvigorfile.ts new file mode 100644 index 00000000..c6edcd90 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/scenario/MusicPlayerOnline/entry/obfuscation-rules.txt b/scenario/MusicPlayerOnline/entry/obfuscation-rules.txt new file mode 100644 index 00000000..985b2aeb --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/obfuscation-rules.txt @@ -0,0 +1,18 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/oh-package.json5 b/scenario/MusicPlayerOnline/entry/oh-package.json5 new file mode 100644 index 00000000..248c3b75 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/entryability/EntryAbility.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 00000000..9656d540 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import hilog from '@ohos.hilog'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; +import PlayerManager from '../manager/PlayerManager'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + AppStorage.setOrCreate('APPContext',this.context); + AppStorage.setOrCreate('PlayerManager', new PlayerManager()); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/manager/PlayerManager.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/manager/PlayerManager.ets new file mode 100644 index 00000000..112f99ae --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/manager/PlayerManager.ets @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 media from '@ohos.multimedia.media'; +import { BusinessError } from '@ohos.base'; +import AudioItem from '../model/AudioItem'; +import Logger from '../utils/Logger'; +import emitter from '@ohos.events.emitter'; +import ServerConstants from '../manager/ServerConstants'; +import backgroundTaskManager from '@ohos.resourceschedule.backgroundTaskManager'; +import wantAgent, { WantAgent } from '@ohos.app.ability.wantAgent'; +import common from '@ohos.app.ability.common'; + +export default class PlayerManager { + private tag: string = 'PlayerManager'; + private isSeek: boolean = false; + private avPlayer: media.AVPlayer | undefined = undefined; + private list: AudioItem[] = []; + private currentTime: number = 0; + private currentDuration: number = 0; + private item: AudioItem = new AudioItem('', '', ''); + private listPosition: number = 0; + private state: string = ServerConstants.PLAYER_STATE_UNKNOWN; + private listTitle: string = ''; + private emitterOptions: emitter.Options = { + priority: emitter.EventPriority.HIGH + }; + + // 注册avplayer回调函数 + setAVPlayerCallback(avPlayer: media.AVPlayer) { + // seek操作结果回调函数 + avPlayer.on('seekDone', (seekDoneTime: number) => { + console.info(`PlayerManager seek succeeded, seek time is ${seekDoneTime}`); + }) + // error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程 + avPlayer.on('error', (err: BusinessError) => { + console.error(`Invoke PlayerManager failed, code is ${err.code}, message is ${err.message}`); + avPlayer.reset(); // 调用reset重置资源,触发idle状态 + }) + // 状态机变化回调函数 + avPlayer.on('timeUpdate', (time: number) => { + //console.info('AVPlayer state timeUpdate:'+time); + this.currentTime = time; + let eventData: emitter.EventData = { + data: { + "currentTime": this.currentTime, + "currentDuration": this.currentDuration + } + }; + emitter.emit(ServerConstants.UPDATE_TIME_EVENT_ID, this.emitterOptions, eventData); + }) + avPlayer.on('durationUpdate', (time: number) => { + console.info('PlayerManager state durationUpdate:' + time); + this.currentDuration = time; + }) + avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => { + this.state = state; + let eventData: emitter.EventData = { + data: { + "state": state, + } + }; + emitter.emit(ServerConstants.UPDATE_STATE_EVENT_ID, this.emitterOptions, eventData); + switch (state) { + case ServerConstants.PLAYER_STATE_IDLE: // 成功调用reset接口后触发该状态机上报 + console.info('PlayerManager state idle called.'); + avPlayer.release(); // 调用release接口销毁实例对象 + break; + case ServerConstants.PLAYER_STATE_INITIALIZED: // avplayer 设置播放源后触发该状态上报 + console.info('PlayerManager state initialized called.'); + avPlayer.prepare(); + break; + case ServerConstants.PLAYER_STATE_PREPARED: // prepare调用成功后上报该状态机 + console.info('PlayerManager state prepared called.'); + avPlayer.play(); // 调用播放接口开始播放 + break; + case ServerConstants.PLAYER_STATE_PLAYING: // play成功调用后触发该状态机上报 + console.info('PlayerManager state playing called.'); + this.list[this.listPosition].isPlaying = true; + this.startContinuousTask(); + break; + case ServerConstants.PLAYER_STATE_PAUSED: // pause成功调用后触发该状态机上报 + console.info('PlayerManager state paused called.'); + break; + case ServerConstants.PLAYER_STATE_COMPLETED: // 播放结束后触发该状态机上报 + console.info('PlayerManager state completed called.'); + avPlayer.stop(); //调用播放结束接口 + this.next(); + break; + case ServerConstants.PLAYER_STATE_STOPPED: // stop接口成功调用后触发该状态机上报 + console.info('PlayerManager state stopped called.'); + this.stopContinuousTask(); + this.currentTime = 0; + Logger.info(this.tag, 'Stop:' + this.item.title); + avPlayer.reset(); // 调用reset接口初始化avplayer状态 + break; + case ServerConstants.PLAYER_STATE_RELEASED: + console.info('PlayerManager state released called.'); + break; + default: + console.info('PlayerManager state unknown called.'); + break; + } + }) + } + + /** + * 初始化 + */ + playList(listTitle: string, list: AudioItem[], item: AudioItem): void { + this.stop(); + if (list.length <= 0) { + Logger.error(this.tag, 'PlayList:' + 'list length <= 0'); + return; + } + this.list = list; + this.listTitle = listTitle; + this.play(item); + } + + getCurrentPlayList(): AudioItem[] { + return this.list; + } + + /** + * 播放 + */ + resume(): void { + if (this.state === ServerConstants.PLAYER_STATE_PAUSED) { + if (this.avPlayer !== undefined) { + this.avPlayer.play(); + } + } + } + + /** + * 播放 + */ + play(item: AudioItem): void { + this.stop(); + Logger.info(this.tag, 'Play finish:' + this.listPosition.toString()); + let index = -1 + if (item !== undefined) { + index = this.list.indexOf(item) + } + if (-1 === index) { + this.listPosition = 0; + } else { + this.listPosition = index; + } + Logger.info(this.tag, 'Play :' + this.listPosition.toString()); + this.item = this.list[this.listPosition] + this.avPlayerLive(ServerConstants.PLAY_SONG_URL + this.item.id); + } + + /** + * 暂停 + */ + pause(): void { + if (this.avPlayer !== undefined) { + this.avPlayer.pause(); + } + } + + /** + * 停止 + */ + stop(): void { + if (this.avPlayer !== undefined) { + this.avPlayer.stop(); + if (this.list.length > this.listPosition) { + this.list[this.listPosition].isPlaying = false; + } + } + } + + /** + * seek + */ + seek(duration: number): void { + if (this.avPlayer !== undefined && this.isSeek) { + this.avPlayer.seek(duration); + } + } + + /** + * 下一首 + */ + next(): void { + let newPosition = 0; + if (this.listPosition + 1 === this.list.length) { + newPosition = 0; + } else { + newPosition = this.listPosition + 1; + } + Logger.info(this.tag, 'Play next:' + newPosition.toString()); + this.play(this.list[newPosition]); + } + + /** + * 上一首 + */ + previous() { + let newPosition = 0; + if (this.listPosition === 0) { + newPosition = 0; + } else { + newPosition = this.listPosition - 1; + } + Logger.info(this.tag, 'Play previous:' + newPosition.toString()); + this.play(this.list[newPosition]); + } + + //播放顺序 + setPlayMode() { + + } + + getItem(): AudioItem { + return this.item; + } + + getListTitle(): string { + return this.listTitle; + } + + getState(): string { + return this.state; + } + + async avPlayerLive(url: string) { + // 创建avPlayer实例对象 + if (this.avPlayer === undefined) { + this.avPlayer = await media.createAVPlayer(); + this.setAVPlayerCallback(this.avPlayer); + } else { + this.avPlayer.release(); + this.avPlayer = await media.createAVPlayer(); + this.setAVPlayerCallback(this.avPlayer); + } + console.info('PlayerManager state url:' + url); + this.avPlayer.url = url; + } + + startContinuousTask() { + let wantAgentInfo: wantAgent.WantAgentInfo = { + wants: [ + { + bundleName: "com.example.avplayer", + abilityName: "EntryAbility" + } + ], + operationType: wantAgent.OperationType.START_ABILITY, + requestCode: 0, + wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] + }; + + try { + wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => { + try { + backgroundTaskManager.startBackgroundRunning(AppStorage.get('APPContext') as common.UIAbilityContext, + backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, wantAgentObj).then(() => { + console.info("PlayerManager Operation startBackgroundRunning succeeded"); + }).catch((error: BusinessError) => { + console.error(`PlayerManager Operation startBackgroundRunning failed. code is ${error.code} message is ${error.message}`); + }); + } catch (error) { + console.error(`PlayerManager Operation startBackgroundRunning failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`); + } + }); + } catch (error) { + console.error(`PlayerManager Operation getWantAgent failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`); + } + } + + // cancel continuous task + stopContinuousTask(): void { + try { + backgroundTaskManager.stopBackgroundRunning(AppStorage.get('APPContext') as common.UIAbilityContext).then(() => { + console.info("PlayerManager Operation stopBackgroundRunning succeeded"); + }).catch((error: BusinessError) => { + console.error(`PlayerManager Operation stopBackgroundRunning failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`); + }); + } catch (error) { + console.error(`PlayerManager Operation stopBackgroundRunning failed. code is ${(error as BusinessError).code} message is ${(error as BusinessError).message}`); + } + } +} + diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/manager/ServerConstants.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/manager/ServerConstants.ets new file mode 100644 index 00000000..2b26c1a6 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/manager/ServerConstants.ets @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +/** + * Common constants for all features. + */ +export default class ServerConstants { + /** + * server host ,replace with your owen server address + */ + static readonly SERVER_HOST = 'http://192.168.62.240:8000/'; + /** + * All songs URL + */ + static readonly ALL_SONGS_URL = this.SERVER_HOST + 'all_songs1'; + /** + * English songs URL + */ + static readonly ENGLISH_SONGS_URL = this.SERVER_HOST + 'english_songs'; + /** + * Song Image URL + */ + static readonly SONG_IMAGE_URL = this.SERVER_HOST + 'get_song_img/'; + /** + * Play songs URL + */ + static readonly PLAY_SONG_URL = this.SERVER_HOST + 'play_song1/'; + + static readonly PLAYER_STATE_IDLE = 'idle'; + static readonly PLAYER_STATE_INITIALIZED = 'initialized' + static readonly PLAYER_STATE_PREPARED = 'prepared' + static readonly PLAYER_STATE_PLAYING = 'playing' + static readonly PLAYER_STATE_PAUSED = 'paused' + static readonly PLAYER_STATE_COMPLETED = 'completed' + static readonly PLAYER_STATE_STOPPED = 'stopped' + static readonly PLAYER_STATE_RELEASED = 'released' + static readonly PLAYER_STATE_UNKNOWN = 'unknown' + + static readonly UPDATE_TIME_EVENT_ID = '1' + static readonly UPDATE_STATE_EVENT_ID = '2' +} + diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/model/AudioItem.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/model/AudioItem.ets new file mode 100644 index 00000000..cf2a9fe8 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/model/AudioItem.ets @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +/** + * AudioItem data entity. + */ + +export default class AudioItem { + title: string = ''; + artist: string = ''; + id: string = '0' + isPlaying: boolean = false; + + constructor(title: string, artist: string, id:string) { + this.title = title; + this.artist = artist; + this.id = id; + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/model/LrcLine.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/model/LrcLine.ets new file mode 100644 index 00000000..af6f3a63 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/model/LrcLine.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +/** + * List item data entity. + */ +export default class LrcLine { + time: string; + title: string; + + + constructor(time: string, title: string) { + this.title = title; + this.time = time; + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/model/PlayListData.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/model/PlayListData.ets new file mode 100644 index 00000000..a5ba5433 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/model/PlayListData.ets @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 AudioItem from './AudioItem'; + +/** + * List item data entity. + */ +export default class PlayList { + /** + * Text of list item. + */ + title: string; + /** + * Image of list item. + */ + img: Resource; + /** + * Other resource of list item. + */ + others?: string; + subTitle: string + list: AudioItem[] = [] + + constructor(title: string, img: Resource, subTitle: string, list: AudioItem[], others?: string) { + this.title = title; + this.img = img; + this.others = others; + this.subTitle = subTitle; + this.list = list; + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/pages/Index.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/pages/Index.ets new file mode 100644 index 00000000..2ec48682 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 PlayerBar from '../view/PlayerBar'; +import PlayList from '../view/PlayList'; +import curves from '@ohos.curves'; +import PlayListItem from '../view/PlayListItem'; +import http from '@ohos.net.http' +import ServerConstants from '../manager/ServerConstants'; +import AudioItem from '../model/AudioItem'; +import PlayListData from '../model/PlayListData'; +import PlayerDetail from '../view/PlayerDetail'; +import emitter from '@ohos.events.emitter'; + +@Entry +@Component +struct Index { + @State playLists: PlayListData[] = []; + @State isShowPlayerDetail: boolean = false; + @State isShowPlayList: boolean = false; + @State isRefreshing: boolean = false + @State mOffset: number = 0 + @State mFriction: number = 48 + @State maskOpacity: number = 0.5; + + @Builder + refreshBuilder() { + Column() { + Text('刷新中......') + .fontSize(16) + } + .alignItems(HorizontalAlign.Center) + .justifyContent(FlexAlign.Center) + .padding(24) + .borderRadius(12) + } + + aboutToAppear(): void { + this.getListFromServer(); + } + + aboutToDisappear(): void { + emitter.off(ServerConstants.UPDATE_TIME_EVENT_ID); + emitter.off(ServerConstants.UPDATE_STATE_EVENT_ID); + } + + build() { + Column() { + Stack({ alignContent: Alignment.Bottom }) { + Refresh({ + refreshing: $$this.isRefreshing, + offset: this.mOffset, + friction: this.mFriction, + builder: this.refreshBuilder + }) { + Scroll() { + Column() { + Row() { + Text('推荐歌单') + .fontSize('20fp') + .fontWeight(FontWeight.Medium) + Image($r('app.media.ic_public_arrow_right')) + .objectFit(ImageFit.Contain) + .width(24) + .height(24) + } + .height(36) + .justifyContent(FlexAlign.SpaceBetween) + .width('90%') + .margin(12) + + Grid() { + ForEach(this.playLists, (item: PlayListData) => { + GridItem() { + PlayListItem({ item }) + } + }) + } + .margin(12) + .columnsTemplate('1fr 1fr 1fr') + .columnsGap(8) + .rowsGap(12) + .width('90%') + }.align(Alignment.TopStart) + }.scrollBarWidth(0) + .height('100%') + .margin({ bottom: 112 }) + }.onRefreshing(() => { + setTimeout(() => { + this.getListFromServer(); + this.isRefreshing = false + }, 500) + }) + + PlayerBar({ isShowPlayList: $isShowPlayList, isShowPlayerDetail: $isShowPlayerDetail }) + .backgroundColor(Color.White) + .width('100%') + if (this.isShowPlayerDetail) { + PlayerDetail({ isShowPlayList: $isShowPlayList, isShowPlayerDetail: $isShowPlayerDetail }) + .width('100%') + .height('100%') + .transition(TransitionEffect.OPACITY + .animation({ curve: curves.springMotion() }) + .combine(TransitionEffect.move(TransitionEdge.BOTTOM))) + } + if (this.isShowPlayList) { + Rect() + .width('100%') + .height('100%') + .fill('#e0e0e0') + .fillOpacity(this.maskOpacity) + .onClick(() => { + animateTo({ duration: 350 }, () => { + this.isShowPlayList = false; + }) + }) + .transition(TransitionEffect.OPACITY) + } + if (this.isShowPlayList) { + PlayList() + .width('100%') + .height('80%') + .transition(TransitionEffect.OPACITY + .animation({ curve: curves.springMotion() }) + .combine(TransitionEffect.move(TransitionEdge.BOTTOM))) + } + } + .width('100%') + .height('100%') + } + .width('100%') + } + + onBackPress() { + if (this.isShowPlayList) { + animateTo({ duration: 350 }, () => { + this.isShowPlayList = false; + }) + return true; + } else if (this.isShowPlayerDetail) { + animateTo({ duration: 350 }, () => { + this.isShowPlayerDetail = false; + }) + return true; + } else { + return false; + } + } + + getListFromServer() { + this.playLists = []; + try { + let httpRequest = http.createHttp() + httpRequest.request(ServerConstants.ALL_SONGS_URL, (err: Error, data: http.HttpResponse) => { + if (!err) { + console.info('HttpResponse Result:' + data.result); + let aPlayingList: AudioItem[] = Array(); + // 解析 JSON 字符串为对象 + const jsonObject: object = JSON.parse(data.result as string); + Object.keys(jsonObject).forEach((key) => { + aPlayingList.push(new AudioItem(jsonObject[key].name, jsonObject[key].singer, jsonObject[key].id)); + }); + this.playLists.push(new PlayListData('全部歌曲', $r('app.media.icon'), aPlayingList.length + '首', + aPlayingList, '')); + console.info('HttpResponse code:' + data.responseCode); + console.info('HttpResponse type:' + JSON.stringify(data.resultType)); + console.info('HttpResponse header:' + JSON.stringify(data.header)); + console.info('HttpResponse cookies:' + data.cookies); // 自API version 8开始支持cookie + + } else { + console.info('HttpResponse error:' + JSON.stringify(err)); + } + }); + } catch (err) { + console.info('HttpRequest error:' + JSON.stringify(err)); + } + try { + let httpRequest = http.createHttp() + httpRequest.request(ServerConstants.ENGLISH_SONGS_URL, (err: Error, data: http.HttpResponse) => { + if (!err) { + console.info('HttpResponse Result:' + data.result); + let aPlayingList: AudioItem[] = Array(); + // 解析 JSON 字符串为对象 + const jsonObject: object = JSON.parse(data.result as string); + Object.keys(jsonObject).forEach((key) => { + aPlayingList.push(new AudioItem(jsonObject[key].name, jsonObject[key].singer, jsonObject[key].id)); + }); + this.playLists.push(new PlayListData('英文歌曲', $r('app.media.icon'), aPlayingList.length + '首', + aPlayingList, '')); + console.info('HttpResponse code:' + data.responseCode); + console.info('HttpResponse type:' + JSON.stringify(data.resultType)); + console.info('HttpResponse header:' + JSON.stringify(data.header)); + console.info('HttpResponse cookies:' + data.cookies); // 自API version 8开始支持cookie + } else { + console.info('HttpResponse error:' + JSON.stringify(err)); + } + }); + } catch (err) { + console.info('HttpRequest error:' + JSON.stringify(err)); + } + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/utils/CommonUtils.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/utils/CommonUtils.ets new file mode 100644 index 00000000..694bac6c --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/utils/CommonUtils.ets @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 HashMap from '@ohos.util.HashMap'; // 导入HashMap模块 +import LrcLine from '../model/LrcLine'; + +/** + * Binds data to components and provides interfaces. + */ +export class CommonUtils { + private lrcs: HashMap = new HashMap(); + private setLrcs() { + this.lrcs.set('十一种孤独', '[ti:十一种孤独]\n[ar:宿羽阳]\n[al:宿羽阳]\n[by:]\n[offset:0]\n[00:00.46]十一种孤独 - 宿羽阳\n[00:00.78]词:陶小陶\n[00:00.96]曲:宿羽阳\n[00:01.14]编曲:谭侃侃\n[00:01.89]\n[00:30.75]最孤独是读评论区未署名情书\n[00:34.85]\n[00:37.27]像不小心掀开了时光的典故\n[00:41.47]\n[00:44.37]第十是睁开眼就已黄昏迟暮\n[00:48.21]\n[00:51.10]寒星三两落在远远处\n[00:55.48]\n[00:57.95]第九是海蓝时见鲸 林深时见鹿\n[01:01.92]\n[01:04.66]却不见你 在梦醒之处\n[01:08.94]\n[01:11.47]第八是回家的路途绕了几次远路\n[01:16.10]\n[01:18.06]像电台的老情歌循环着音符\n[01:22.34]\n[01:24.84]愿你风尘仆仆 深情不被辜负\n[01:29.32]\n[01:31.41]虽回不到过去 也回不到当初\n[01:36.60]\n[01:38.46]愿你半生漂浮此生能有归宿\n[01:42.99]\n[01:45.20]愿你风雨落幕能有人免你孤苦\n[01:50.38]\n[02:05.91]第七是看一场一群人的演出\n[02:10.02]\n[02:12.61]荧光满眼却看不清楚\n[02:16.74]\n[02:19.44]第六是一个人吃饭 一个人写书\n[02:23.47]\n[02:26.19]一个人拼岁月拼图\n[02:30.43]\n[02:33.03]第五是骑单车过陌生的马路\n[02:37.04]\n[02:39.49]在拥挤的人海中踌躇\n[02:43.57]\n[02:46.52]第四是给空白的纸上画上五线谱\n[02:51.28]\n[02:53.24]每一行都好像是世界的遗嘱\n[02:57.49]\n[02:59.96]愿你风尘仆仆 深情不被辜负\n[03:04.62]\n[03:06.69]虽回不到过去 也回不到当初\n[03:11.60]\n[03:13.38]愿你半生漂浮此生能有归宿\n[03:18.10]\n[03:20.19]愿你风雨落幕能有人免你孤苦\n[03:25.11]\n[03:27.10]愿你风尘仆仆 深情不被辜负\n[03:32.01]\n[03:33.82]虽回不到过去 也回不到当初\n[03:38.70]\n[03:40.52]愿你半生漂浮此生能有归宿\n[03:45.84]\n[03:47.32]愿你风雨落幕能有人免你孤独\n[03:51.97]\n[03:54.58]第三是假装很成熟 假装很忙碌\n[03:58.60]\n[04:01.25]假装擅长一个人独处\n[04:05.28]\n[04:07.94]第二是穿过万家灯火无数\n[04:12.10]\n[04:14.85]却无一人等我在归途\n[04:18.96]\n[04:21.74]第一是收到远方一纸家书\n[04:25.65]\n[04:28.18]说照顾自己 累了别忍着不哭') + } + + getLrc(name: string): LrcLine[] { + let lrcData: LrcLine[] = []; + let lrc = this.lrcs.get(name); + if (lrc !== null && lrc !== undefined) { + let lines = lrc.split('\n'); + // Create an array to store the LRC data + for (let line of lines) { + // Check if the line is a valid LRC line + if (line.includes('[')) { + // Split the line into the time and text components + let content = line.split(']'); + // Add the time and text to the LRC data array + if (content.length > 1 && content[1].trim() !== '') { + lrcData.push(new LrcLine(content[0], content[1])); + } + } + } + } + // Return the LRC data array + return lrcData; + } + formatTime(time: number): string { + let min = Math.floor(time / 60).toString(); + let sec = Math.floor((time % 60)).toString() + if (sec.length === 1) { + sec = '0' + sec; + } + if (min.length === 1) { + min = '0' + min; + } + return min + ':' + sec; + } +} +export default new CommonUtils(); \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/utils/Logger.ts b/scenario/MusicPlayerOnline/entry/src/main/ets/utils/Logger.ts new file mode 100644 index 00000000..89b6f97a --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/utils/Logger.ts @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Hunan OpenValley Digital Industry Development 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'; + +class Logger { + private domain: number; + private prefix: string; + private format: string = '%{public}s, %{public}s'; + + constructor(prefix: string) { + this.prefix = prefix; + this.domain = 0xFF00; + } + + debug(...args: string[]): void { + hilog.debug(this.domain, this.prefix, this.format, args); + } + + info(...args: string[]): void { + hilog.info(this.domain, this.prefix, this.format, args); + } + + warn(...args: string[]): void { + hilog.warn(this.domain, this.prefix, this.format, args); + } + + error(...args: string[]): void { + hilog.error(this.domain, this.prefix, this.format, args); + } +} + +export default new Logger('[Samples_MusicPlayer]'); \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayList.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayList.ets new file mode 100644 index 00000000..54aa274c --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayList.ets @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 AudioItem from '../model/AudioItem'; +import PlayerManager from '../manager/PlayerManager' +import SongCell from './SongCell'; +import emitter from '@ohos.events.emitter'; +import ServerConstants from '../manager/ServerConstants'; + +@Component +export default struct PlayList { + @State playingList: AudioItem[] = Array(); + @State listTitle: string = '没有播放' + private playerManager: PlayerManager = AppStorage.get('PlayerManager') as PlayerManager; + + aboutToAppear() { + this.playingList = this.playerManager.getCurrentPlayList(); + this.listTitle = this.playerManager.getListTitle(); + emitter.on(ServerConstants.UPDATE_STATE_EVENT_ID, (eventData: emitter.EventData) => { + if (eventData !== undefined && eventData.data !== undefined) { + this.playingList = this.playerManager.getCurrentPlayList(); + } + }); + } + + aboutToDisappear(): void { + } + + build() { + Column() { + Text(this.listTitle) + .fontSize(24) + .margin(8) + .fontWeight(FontWeight.Bold) + Scroll() { + Column({ space: 10 }) { + List() { + ForEach(this.playingList, (item: AudioItem) => { + ListItem() { + SongCell({ item }) + } + .width('100%') + .backgroundColor(item.isPlaying ? '#f6f6f6' : Color.White) + .onClick(() => { + this.playerManager.playList(this.listTitle, this.playingList, item) + }) + .height('84vp') + }) + } + .width('100%') + .backgroundColor(Color.White) + } + .width('100%') + } + .margin({ bottom: 36 }) + .width('100%') + } + .backgroundColor(Color.White) + .borderRadius({ topLeft: '18vp', topRight: '18vp' }) + } +} diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayListItem.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayListItem.ets new file mode 100644 index 00000000..8a7e4662 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayListItem.ets @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 ItemData from '../model/PlayListData'; +import hilog from '@ohos.hilog'; +import prompt from '@ohos.promptAction'; +import PlayerManager from '../manager/PlayerManager'; +import ServerConstants from '../manager/ServerConstants'; + +/** + * List item information component. + */ +@Component +export default struct PlayListItem { + private item: ItemData = new ItemData('', $r('app.media.icon'), '', [], ''); + private PlayerManager: PlayerManager = AppStorage.get('PlayerManager') as PlayerManager; + + aboutToAppear() { + } + + build() { + Column() { + Column() { + Row() { + Text(this.item.subTitle) + .fontSize(16) + .margin(8) + .fontColor(Color.White) + Blank() + Image($r('app.media.ic_public_play_white')) + .width(20) + .height(20) + .margin(8) + } + .width('100%') + } + .borderRadius(12) + .backgroundImage(this.item.list.length > 0 ? ServerConstants.SONG_IMAGE_URL + this.item.list[0].id : this.item.img) + .backgroundImageSize(ImageSize.Cover) + .width(120) + .height(120) + .justifyContent(FlexAlign.SpaceBetween) + + Text(this.item.title) + .fontSize('20fp') + .maxLines(2) + .margin({ top: 4 }) + } + .alignItems(HorizontalAlign.Center) + .onClick(() => { + this.enterList(); + }) + } + + enterList() { + prompt.showToast({ + message: '播放歌单:' + this.item.title + }) + if (this.item.list.length > 0) { + this.PlayerManager.playList(this.item.title, this.item.list, this.item.list[0]) + } + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerBar.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerBar.ets new file mode 100644 index 00000000..cc9fab99 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerBar.ets @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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. + */ + +/** + * List item information component. + */ +import emitter from '@ohos.events.emitter'; +import Logger from '../utils/Logger'; +import AudioItem from '../model/AudioItem'; +import ServerConstants from '../manager/ServerConstants'; +import PlayerManager from '../manager/PlayerManager'; + +@Component +export default struct PlayerBar { + private tag: string = 'PlayerBar'; + @State item: AudioItem = new AudioItem('', '', '') + @State rotateAngle: number = 0; + @State durationTime: number = 100; + @State currentTime: number = 0; + @State state: string = ServerConstants.PLAYER_STATE_UNKNOWN; + @Link isShowPlayList: boolean; + @Link isShowPlayerDetail: boolean; + private PlayerManager: PlayerManager = AppStorage.get('PlayerManager') as PlayerManager; + + aboutToAppear() { + Logger.info(this.tag, 'aboutToAppear'); + emitter.on(ServerConstants.UPDATE_TIME_EVENT_ID, (eventData: emitter.EventData) => { + if (eventData !== undefined && eventData.data !== undefined) { + //Logger.info(this.tag, 'currentTime:' + eventData.data.currentTime); + this.currentTime = eventData.data.currentTime; + this.durationTime = eventData.data.currentDuration; + } + }); + emitter.on(ServerConstants.UPDATE_STATE_EVENT_ID, (eventData: emitter.EventData) => { + if (eventData !== undefined && eventData.data !== undefined) { + Logger.info(this.tag, 'state:' + eventData.data.state); + if (this.state !== ServerConstants.PLAYER_STATE_PLAYING && eventData.data.state === ServerConstants.PLAYER_STATE_PLAYING) { + this.item = this.PlayerManager.getItem(); + if (this.rotateAngle === 0) { + this.rotateAngle = 360; + Logger.info(this.tag, 'rotateAngle:360'); + } + } + if (eventData.data.state !== ServerConstants.PLAYER_STATE_PLAYING) { + this.rotateAngle = 0; + Logger.info(this.tag, 'rotateAngle:0'); + } + this.state = eventData.data.state; + } + }); + } + + aboutToDisappear() { + Logger.info(this.tag, 'aboutToDisappear'); + emitter.off(ServerConstants.UPDATE_TIME_EVENT_ID); + emitter.off(ServerConstants.UPDATE_STATE_EVENT_ID); + } + + build() { + Column() { + Row() { + Image(ServerConstants.SONG_IMAGE_URL + this.item.id) + .width(64) + .height(64) + .margin(4) + .borderRadius(48) + .rotate({ angle: this.rotateAngle }) + .animation({ + duration: 3600, + curve: Curve.Linear, + delay: 500, + iterations: -1, + playMode: PlayMode.Normal + }) + Text(this.item.title !== '' ? this.item.title + ' - ' + this.item.artist : '未播放') + .fontSize('24fp') + .fontWeight(FontWeight.Bold) + .maxLines(1) + .textOverflow({ overflow: TextOverflow.MARQUEE }) + .width('60%') + .textAlign(TextAlign.Center) + + Blank() + Stack() { + Row({ space: 40 }) { + Progress({ value: 0, total: this.durationTime, type: ProgressType.Ring }) + .color(Color.Black) + .value(this.currentTime) + .width('100%') + .height('100%') + .style({ strokeWidth: '2vp' }) + } + + if (this.state === ServerConstants.PLAYER_STATE_PLAYING) { + Image($r('app.media.ic_public_pause')) + .objectFit(ImageFit.Contain) + .width('90%') + .height('90%') + .padding('4vp') + .onClick(() => { + this.PlayerManager.pause(); + }) + } else { + Image($r('app.media.ic_public_play')) + .objectFit(ImageFit.Contain) + .width('90%') + .height('90%') + .padding('4vp') + .onClick(() => { + this.PlayerManager.resume(); + }) + } + }.alignContent(Alignment.Center) + .width(42) + .height(42) + .margin({ right: 8 }) + + Image($r('app.media.ic_public_view_list')) + .objectFit(ImageFit.Contain) + .width(42) + .height(42) + .margin({ right: 8, left: 8 }) + .onClick(() => { + animateTo({ duration: 350 }, () => { + this.isShowPlayList = true; + }) + }) + } + .width('100%') + .onClick(() => { + animateTo({ duration: 350 }, () => { + this.isShowPlayerDetail = true; + }) + }) + + Divider().strokeWidth(1).color('#E0E0E0') + } + .width('100%') + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerDetail.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerDetail.ets new file mode 100644 index 00000000..bf69c03c --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/view/PlayerDetail.ets @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 PlayerManager from '../manager/PlayerManager'; +import emitter from '@ohos.events.emitter'; +import Logger from '../utils/Logger'; +import LrcLine from '../model/LrcLine'; +import CommonUtils from '../utils/CommonUtils'; +import ServerConstants from '../manager/ServerConstants'; +import AudioItem from '../model/AudioItem'; + +/** + * Setting tab content + */ +@Component +export default struct PlayerDetail { + private tag: string = 'PlayerDetail'; + private PlayerManager: PlayerManager = AppStorage.get('PlayerManager') as PlayerManager; + @State item:AudioItem = this.PlayerManager.getItem(); + @State listTitle: string = this.PlayerManager.getListTitle(); + @State durationTime: number= 0; + @State currentTime: number = 0; // 当前时间 + @State state: string = this.PlayerManager.getState(); // 播放状态 + @State rotateAngle: number = 0; + @State subCurrentIndex: number = 0; + @State lrcIndex: number = 0 + @State lrc: LrcLine[]= []; + @State contentSwitch: boolean = true; + @Link isShowPlayList: boolean; + @Link isShowPlayerDetail: boolean; + private scroller: Scroller = new Scroller() + private tabsController: TabsController = new TabsController(); + + @Builder + TabBuilder(title: string, index: number, selectedImg: Resource, normalImg: Resource) { + Column() { + Row() { + Text(title) + .fontSize('20fp') + .fontColor(this.subCurrentIndex === index ? '#E02020' : '#6B6B6B') + }.alignItems(VerticalAlign.Top) + + Image(this.subCurrentIndex === index ? selectedImg : normalImg) + .width(25) + } + .height(60) + .margin({ + top: 12, + left: 12, + right: 12 + }) + .onClick(() => { + this.subCurrentIndex = index; + this.tabsController.changeIndex(this.subCurrentIndex); + }) + } + + aboutToAppear() { + emitter.on(ServerConstants.UPDATE_TIME_EVENT_ID, (eventData: emitter.EventData) => { + if (eventData !== undefined && eventData.data !== undefined) { + //Logger.info(this.tag, 'currentTime:' + eventData.data.currentTime); + this.currentTime = eventData.data.currentTime; + this.durationTime = eventData.data.currentDuration; + let newLrcIndex = Math.floor(this.currentTime * this.lrc.length / this.durationTime); + if (newLrcIndex !== this.lrcIndex){ + this.lrcIndex = newLrcIndex; + this.scroller.scrollToIndex(this.lrcIndex-5, true) + } + } + }); + emitter.on(ServerConstants.UPDATE_STATE_EVENT_ID, (eventData: emitter.EventData) => { + if (eventData !== undefined && eventData.data !== undefined) { + Logger.info(this.tag, 'state:' + eventData.data.state); + if (this.state !== ServerConstants.PLAYER_STATE_PLAYING && eventData.data.state === ServerConstants.PLAYER_STATE_PLAYING) { + this.item = this.PlayerManager.getItem(); + this.lrc = CommonUtils.getLrc(this.item.title); + this.listTitle = this.PlayerManager.getListTitle(); + this.scroller.scrollToIndex(0, true) + if (this.rotateAngle === 0) { + this.rotateAngle = 360; + Logger.info(this.tag, 'rotateAngle:360'); + } + } + if (eventData.data.state !== ServerConstants.PLAYER_STATE_PLAYING) { + this.rotateAngle = 0; + Logger.info(this.tag, 'rotateAngle:0'); + } + this.state = eventData.data.state; + } + }); + if (this.state === ServerConstants.PLAYER_STATE_PLAYING) { + setTimeout(() => { + if (this.rotateAngle === 0) { + this.rotateAngle = 360; + Logger.info(this.tag, 'rotateAngle:360'); + } + }, 100); + } + } + + aboutToDisappear() { + } + + build() { + Column() { + Row() { + Image($r('app.media.ic_public_arrow_down_0')) + .height('48vp') + .width('48vp') + .padding('8vp') + .onClick(() => { + animateTo({ duration: 350 }, () => { + this.isShowPlayerDetail = false; + }) + }) + Column() { + if (this.contentSwitch) { + Text(this.listTitle).fontSize('18fp') + .maxLines(2) + } else { + Text(this.item.title).fontSize('18fp') + .maxLines(1) + Row() { + Text(this.item.artist).fontSize('14fp') + .fontColor('#a0a0a0') + Text('关注') + .fontSize('14fp') + .borderRadius('8vp') + .backgroundColor('#22a0a0a0') + .margin('4vp') + .padding({ right: '4vp', left: '4vp' }) + Image($r('app.media.ic_public_arrow_right_grey')) + .width('8vp') + .height('16vp') + } + } + } + .justifyContent(FlexAlign.Center) + .height('60vp') + .width('70%') + + Image($r('app.media.ic_public_share')) + .height('32vp') + .width('32vp') + } + .width('100%') + .justifyContent(FlexAlign.SpaceEvenly) + + Column() { + if (this.contentSwitch) { + Column() { + Image(ServerConstants.SONG_IMAGE_URL + this.item.id) + .width('300vp') + .height('300vp') + .borderRadius('200vp') + .margin('50vp') + .rotate({ angle: this.rotateAngle }) + .animation({ + duration: 3600, + curve: Curve.Linear, + delay: 500, + iterations: -1, // 设置-1表示动画无限循环 + playMode: PlayMode.Normal + }) + Row() { + Column() { + Text(this.item.title).fontSize('18fp') + Row() { + Text(this.item.artist).fontSize('16fp') + .fontColor('#303030') + Text('关注') + .fontSize('14fp') + .fontColor('#303030') + .backgroundColor('#f0f0f0') + .borderRadius('6vp') + .padding({ left: '4vp', right: '4vp' }) + } + }.alignItems(HorizontalAlign.Start) + + Blank() + Stack() { + Image($r('app.media.ic_public_favor')) + .width('36vp') + .height('36vp') + Text('100w+').fontSize('10fp') + .backgroundColor('#ffffff') + .margin({ left: '24vp' }) + }.alignContent(Alignment.Top) + .margin({ right: '8vp' }) + + Stack() { + Image($r('app.media.ic_public_comments')) + .width('36vp') + .height('36vp') + Text('10w+').fontSize('10fp') + .backgroundColor('#ffffff') + .margin({ left: '24vp' }) + }.alignContent(Alignment.Top) + } + .width('80%') + .justifyContent(FlexAlign.SpaceBetween) + }.width('100%') + .height('100%') + .justifyContent(FlexAlign.SpaceAround) + .onClick(() => { + this.contentSwitch = false; + }) + } else { + Column() { + Tabs({ + barPosition: BarPosition.End, + index: 0, + controller: this.tabsController + }) { + TabContent() { + Column() { + List({ space: 10, scroller: this.scroller }) { + ForEach(this.lrc, (item: LrcLine, index: number) => { + ListItem() { + if (index === this.lrcIndex) { + Text(item.title) + .width('100%') + .textAlign(TextAlign.Center) + .fontSize('24fp') + .fontColor(Color.Black) + } else { + Text(item.title) + .width('100%') + .textAlign(TextAlign.Center) + .fontSize('18fp') + .fontColor(Color.Gray) + } + } + }) + } + .width('100%') + }.height('100%') + } + .tabBar(this.TabBuilder('歌词', 0, + $r('app.media.ic_screenshot_line_select'), $r('app.media.ic_screenshot_line'))) + + TabContent() { + Column() { + Scroll() { + Column({ space: 12 }) { + } + } + .width('100%') + }.height('100%') + } + .tabBar(this.TabBuilder('百科', 1, + $r('app.media.ic_screenshot_line_select'), $r('app.media.ic_screenshot_line'))) + } + .width('100%') + .barHeight(60) + .barWidth('70%') + .barMode(BarMode.Scrollable) + .barPosition(BarPosition.Start) + .onChange((index: number) => { + this.subCurrentIndex = index; + }) + } + .width('100%') + .height('100%') + .onClick(() => { + this.contentSwitch = true; + if (this.state === ServerConstants.PLAYER_STATE_PLAYING) { + this.rotateAngle = 0; + animateTo({ duration: 3600 }, () => { + this.rotateAngle = 360; + }) + } + }) + } + }.width('100%') + .height('70%') + + Row() { + Progress({ value: this.currentTime, total: this.durationTime, type: ProgressType.Linear }) + .width('80%') + .height(30) + }.width('100%') + .justifyContent(FlexAlign.Center) + + Row() { + Text(CommonUtils.formatTime(this.currentTime/1000)).fontSize('12fp') + Text('无损').fontSize('12fp') + Text(CommonUtils.formatTime(this.durationTime/1000)).fontSize('12fp') + }.width('80%') + .justifyContent(FlexAlign.SpaceBetween) + + Row() { + Image($r('app.media.ic_public_list_cycle')) + .objectFit(ImageFit.Contain) + .width(42) + .height(42) + .margin({ right: 12, left: 8 }) + Image($r('app.media.ic_public_play_last')) + .objectFit(ImageFit.Contain) + .width(42) + .height(42) + .margin({ right: 12, left: 8 }) + .onClick(() => { + this.PlayerManager.previous(); + }) + if (this.state === ServerConstants.PLAYER_STATE_PLAYING) { + Image($r('app.media.ic_public_pause')) + .objectFit(ImageFit.Contain) + .width(48) + .height(48) + .margin({ right: 12, left: 8 }) + .onClick(() => { + this.PlayerManager.pause(); + }) + } else { + Image($r('app.media.ic_public_play')) + .objectFit(ImageFit.Contain) + .width(48) + .height(48) + .margin({ right: 12, left: '8vp' }) + .onClick(() => { + this.PlayerManager.resume(); + }) + } + Image($r('app.media.ic_public_play_next')) + .objectFit(ImageFit.Contain) + .width(42) + .height(42) + .margin({ right: 12, left: 8 }) + .onClick(() => { + this.PlayerManager.next(); + }) + Image($r('app.media.ic_public_view_list')) + .objectFit(ImageFit.Contain) + .width(42) + .height(42) + .margin({ right: 12, left: 8 }) + .onClick(() => { + animateTo({ duration: 350 }, () => { + this.isShowPlayList = true; + }) + }) + }.width('100%') + .height(64) + .justifyContent(FlexAlign.SpaceEvenly) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('100%') + .backgroundColor(Color.White) + .borderRadius({ topLeft: 18, topRight: 18 }) + } +} diff --git a/scenario/MusicPlayerOnline/entry/src/main/ets/view/SongCell.ets b/scenario/MusicPlayerOnline/entry/src/main/ets/view/SongCell.ets new file mode 100644 index 00000000..05fb0ca1 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/ets/view/SongCell.ets @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 AudioItem from '../model/AudioItem'; +import ServerConstants from '../manager/ServerConstants'; + +@Component +export default struct SongCell { + @State item: AudioItem = new AudioItem('', '', ''); + + build() { + Row() { + Image(ServerConstants.SONG_IMAGE_URL + this.item.id) + .width(64) + .height(64) + Blank() + Text(this.item.title) + .fontSize('20fp') + Text('·') + .fontSize('20fp') + .fontColor('#e0e0e0') + Text(this.item.artist) + .maxLines(1) + .fontSize('14fp') + .fontColor('#e0e0e0') + } + .justifyContent(FlexAlign.SpaceBetween) + .width('90%') + .alignSelf(ItemAlign.Center) + } +} diff --git a/scenario/MusicPlayerOnline/entry/src/main/module.json5 b/scenario/MusicPlayerOnline/entry/src/main/module.json5 new file mode 100644 index 00000000..465a2964 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/module.json5 @@ -0,0 +1,63 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "backgroundModes": [ + "audioPlayback", + "dataTransfer" + ], + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions":[ + { + "name" : "ohos.permission.INTERNET", + "reason": "$string:EntryAbility_desc", + "usedScene": { + "abilities": [ + "EntryAbility" + ], + "when":"inuse" + } + }, + { + "name": "ohos.permission.KEEP_BACKGROUND_RUNNING", + "reason": "$string:keep_running", + "usedScene": { + "abilities": [ + "EntryAbility" + ], + "when": "always" + } + } + ] + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/element/color.json b/scenario/MusicPlayerOnline/entry/src/main/resources/base/element/color.json new file mode 100644 index 00000000..3c712962 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/element/string.json b/scenario/MusicPlayerOnline/entry/src/main/resources/base/element/string.json new file mode 100644 index 00000000..e1d216d9 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/resources/base/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "MusicPlayerOnline" + }, + { + "name": "keep_running", + "value": "长时任务权限" + } + ] +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_arrow_down_0.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_arrow_down_0.png new file mode 100644 index 0000000000000000000000000000000000000000..284284f35b9b6514d3c7a3341b1fc16fd2c481f7 GIT binary patch literal 287 zcmV+)0pR|LP)Px#*-1n}R7gwh)3HheK@^4IZwrw?o=31s<1?g*u~D!Jq>w;T*ad_XY3u|GQLL;4 z!H3Cv*r@|q2rIiYv#?;X0|QgcIsd)q&J;RcMaTYnKs4b#qW>My4llTklzD_Vd|_O@ z+ce}gR=C5m26BvdoMD3396-3c#T@sTRm1~)V1((u+dp-rJkt{LfNOkXh|k}BiYq+U z#h3yJ+6`_HAd9{E2`-z=gD@3v7*{xlE*dK@JIVnB%>~Z!gy-ld$m}4+uho!S8Mlon l8Px#%}GQ-R7gwh)G=y8K@^4I&m!PPEYhUWMj?`&1YCfdaRKfm646xzlN3P&1;IkF z3j^J^i(WCuSEJ&efhgbuZ9L;U2NDHzu*3;{ z{6ry9K+=1}0*7jo5F`hXAWu~m`zRzAkRV;mu)_eGYj*tyko1Ol#}uOyfR}2E3C6bu z^zeplmBad$fTAJS-}IQ%g=ol^Mayb)6!3|MlBXgayVT-U^hDHi(G7BS&+~UcqjkkC Z`UP^uBpF~YGco`G002ovPDHLkV1mJ=aQFZK literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_arrow_right_grey.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_arrow_right_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..c067e4b839d8fdc066932468875ebc07632b3c72 GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|R(ZNOhIn|t zonp&<$U(p*-huaq+oS*gYd2m{VsuT8*tvw`Mcsq4ozG_Nt~_&QljzCiUf0r@S8zrv zTQQYCSgN&7E`m|F=GU$Y#jpc>7L57&N4NwYD|WCeOt8IBF{gsj*yWK_VMf4mdqo^@Q=_|?io*Rs^d`O&3b(?!LaL1$}XcZe#Se#dCD ndD`6Y^2+?u4UC64SIDbNOjVJ*zs&0x(A5l{u6{1-oD!M<48dHt literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_comments.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_comments.png new file mode 100644 index 0000000000000000000000000000000000000000..1201b7a1ae939d2b43abd3761779162eca2d2eb1 GIT binary patch literal 492 zcmVPx$rb$FWR7gw3l}SqjQ4oZ`xZ$pdUc{4#f~Y7_5fS|FUL-DfFvbNz@E}UucRi>S zbcb;q<;^661A*|~bXQkbbx(nupF+<0`4@mDUqndsmi$8=&F;T`CuM@;`9Z1*c94y!zYy$5YL9_{^orX->)#gC?bU9~}s7by~0ir^O z%>O>g8nz$XR64jGVsQ^VnTxcS^fa48qU@Div2t5Ex(Sljwbq9E*l(;9C=gLr@@cyh znC3&3YLjXM+{Ia^`5q|wlqFY{S0OD71;~^Px&JxN4CR7gv;m0xHSR}{v-Gc(&wL~N-cTFhq7-E2fCDkUmD*-!&27Ft?b3+ToGah^LjjIJq@RuXq+a5+?>`5k>kxTbh&C#%bqyiA z2sjIogKW&<44|2R1CX%R>l;;71_4s_AFwe4wd^(Xpa4%Pt=EzC_IgI^DTth8W8QBB zXl7qCp8&Ae*V?6!`56NKnhB{H2aRk(<^u$LJmq;UBmf!a`vjcxwSKG7;b!&?^H~A< zSnIZ#99#s@1R^YClAdk+pq( z6kW~$)7SJJfVGyWrx=FAj{`}2g@79b{Nii<;%uX(ALU}PJF#{U!1#lFe$$%a;k*9_ zGSbym@RHH+PoHqYnYHe(?PrAUdDcc}un0x3W^X-wdSO(eZ5Td8zUa$8olF z206rholMMtn0 Zz`rL^Qc_agy(|C#002ovPDHLkV1gX9sfPdn literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_list_cycle.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_list_cycle.png new file mode 100644 index 0000000000000000000000000000000000000000..a1e95ae27ca18bd9150205bc1de27afc8e812255 GIT binary patch literal 414 zcmV;P0b%}$P)Px$SV=@dR7gwh)jdmGK^VpH--3lmO0h9^CZMQD1iwH)5`vrp2j5J;x2D_HH%)My~g=WMZh*j@ISjR59q@JhHDhhw=H458sG!gaE;G6#!a1| zGh9{zbmK6tcetukIIlT?U*Ti2=o==`i_-$)Ve5PBl-FR{>iq=xixY&?7p+!YV5@BN zXad~g3qBQ9kNel78?O@}4CesjPXt)R3|bOkC5nf;A8t|6+Q1uhBtW?TM;O9xLG_n$ zot<807*qo IM6N<$f{YHX^#A|> literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_pause.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..833902ec7a4362c6a9d1c1fed2975dbd60d31203 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|T0C7GLp;3S zPV?q!FyLWbzC6(J;9(BA!1c-<^Dk%Y78F;z8BsEEUHf;BS@8;=xo3X;d1V1pRRW8d zV$kG^N)Zhz28?SHCiHOkUgYVUz2eBs9_fm%bylCWs@?=|c4CtoUI}bc zi7~T#zMU);dH-mSd_$~(!A$?~XWHK#zH#`?I-(=lu=H9t&^-*Eu6{1-oD!MPx$6G=otR7gw3)xS!^P#A{sUpIH}!P$#&u9x5iC@45cMe*+%-@aE0;rJ?4lQ8VAb1f!V7aB{ydn>3bS1lJf! zpkLU=I^KH~#RRk1ih!Q6h+TXa6~zS0Sjqt0ViM;?BxM9C_ZT7VU6!aHLEwgdcCd=K zn5bVt%6v)sX?ONhl^_+JVEk{Ass(}F#Azz2Lok88x&&e3!xnh0LvVx{JXPJnRWf)N zRez?Bn8!YTx(!>Il0UJD4SeLSimYh4Z=U=9y?;H;9zaMl3`?{^B9MZsBu@T`Ru r+$5{}uvc)Npe*m-xqLxfDPoziN00000NkvXXu0mjf-;$BQ literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play_last.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play_last.png new file mode 100644 index 0000000000000000000000000000000000000000..47f41004c71eecc097c22b8e8bc1b9f81aaf7698 GIT binary patch literal 320 zcmV-G0l)rPx#`bk7VR7gwh)H_N9K@^4IZ-fa=bp^Tr1<}Y*L1SZ$O*9ih&`3=bbQUn_>_!lG zU?yfJqWHKl!q_xjW!argK_|uO^WR6^+tcysb?k2nNLILw5{1Vq?(tG3)&T~1$3ZeY zmT`+UJYflslmFELJ`vwc17Hpp*sExcaG3)LO&z>H&g=xUH36J`-<_5MwsD1phRlip z^B7_?qbEgxX!?GJc}R)?BkXhuSi}uBG9X16{P=F+x{D@H2Hwgu{TMr@1}z3^w^Fua zoTug>UdPx$5J^NqR7gwh)jdkYP!z@S-;@?wS-XJ&!4;?r&<)5Gf{m!4jf#yjBDT5#bq|78 zeijOX*lS@gR@w@h2N?+=$rC0ign3oMyE*^dlXG8M8eXl2^$h?~hs!J)K^yl`g-AgW zU<{8KO#v(EeU;P#W-*7)Y+(^#6Z<)}W31!7gmQ%`OyV{M*ui#z&)C%b7o+5bvmcDhcrVW&i*H07*qoM6N<$f^vwG*#H0l literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play_white.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_public_play_white.png new file mode 100644 index 0000000000000000000000000000000000000000..016a114c2f17eb0fc7030da72f8d7bfc5b161e25 GIT binary patch literal 365 zcmV-z0h0cSP)Px$CrLy>R7gw3mA@_pK^RBR>Ga+~eIG*2BX|H3l3NHN{x(7s+8Ygth)O6`N(lvt zmWGJv2oi;nNp=&tcK7bxyBpI?F`0An&2PRLX?WN$pZ^hr5L&=AFdS#~zG|g^DhMHr z0N21!0{sHEfpzu0Us0Bz4QyqAo`FSRSN$$4$`ULCO9g;iU{XCVBdH=txyL|Ty(Px$dPzhq9VyMO?ubyushD1ZxRy;4!}8I~L0C z&bSC3VFoX8S_qb~iJ!wrYAaaA^%lWB+#e^wO{9u;iw?0nt`=Ryb6mg)zK(myE11P= z9Cc;g{$4YKc|62BeCPw7yIlmAv0jw2-50!u;7L)>t1dbIk9=4Kckuvk@o|*whgFbu zkk-Vtoo*e)XiqVXEgX-U{a^*rdJGlE-Yz=-)B}97#K$XHhJV@w*AT5=Y5``jKPm~5 zRGi+#|H588(+qhHQ-~Dv-zswHeI-E_-(Y-NyVDT7z~^G7U?w0dxzC9SW5y=_4mKKs zXNak?3YrSi!$`E|B%#c(9e<{RtB9$Z9{$EY4r=XYYLC7b~Hb#((tkG{C~$SNBK;@^}Y~Z+;EWj@w$To+H;C>1td)F zURp1*^gD0J7D3&@V=~v>UN=NKd~fqLca3jm)wASbYF-xY)itT-R>!H0*^hr!ubXV6 f%&NM~Gb`V|O+nJHdC_a2YZ*LU{an^LB{Ts5<=9u~ literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_screenshot_line.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_screenshot_line.png new file mode 100644 index 0000000000000000000000000000000000000000..2e373c8d21f6f78e21951aa5ccf7cc1733375217 GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|JUv|;Lp;3S zPTt7NV8C(s#9`ZI{K2I!vkaF6&(LjJv%skT%x`VR42!Ns9J~r2qORQKe#xki8UH8# oz=Iuvv)r9y14Udj7#OR&`PQH3kaVg01TvJt)78&qol`;+0EG81DF6Tf literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_screenshot_line_select.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/ic_screenshot_line_select.png new file mode 100644 index 0000000000000000000000000000000000000000..71c367e35c73fa08fbe796ba3f2591ab1af5eb6e GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|ygXeTLp;2b zQx+H|EZO*zXR(+7&%=ufQoKq{iVgvcHllaK15PNfn8m`{#V_Z>q`7=PtBOUR%F@M> py$J=qY!@>G1bG;nxH9H-F|;ypNP4e}^#hv9;OXk;vd$@?2>?CyCyxLC literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/icon.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd45accb1dfd2fd0da16c732c72faa6e46b26521 GIT binary patch literal 2041 zcmaJ?c~nzZ9u6@;0AXaYAVN(;Kr(@>EJ+}skOWf=BA~*l4us@ELY9{%0m5QX6pnb} z(jZF|S&pLAS}3BZAfeQSvJ_h>F2Q1PYqi?o5`;m_yjZdG$1v}l_wK#F^L^iMz2}uD z#K$>1dON~kFlWvhW+Jp=tuN9J`ZlM-rl4h+ij|^D0y9;4JOuz-EdVnB6i3R-0ulk9 zApi4zAQA>!N9@-o026$1@L`d124`3G5<@_m`0f)Ug_Ie~;HT2q<_a=HH> zDwTdfD^-cW-|_xWVP$f@93UhDN-#&khZ>jZXLTi~$0`7x3REP6pk%&^2|`c>DutjN zMJD4Zs6Z}{FOpd;*mo2zm(GzXRXiCV;4m3zNCYnu3Fy=i5;2An&Lp!#LP;bRD~1&s z%VH6UY+}r6YDgG+p34OJIZ{BTn&%4s=CT&#TBkuOhdeU@g(w#guoa*b^)73=XyI65 z7Swys6)YS}?1EeZ6b!-I+yCnIya^g0>-NLsLWd8t56GZ_S3r|ZGbR+mV2ErEb9J)X zIF!njY-D-7{qtF2(?nlQ$0}!pzt=}hc*m%%)0Jb#N_K4@IC-`Pi5DahPZN7N9rH;ol;Gc*>-Go@gXKTM{eP)iJj6CYTIi}B#zLKZYD@_;m zrXmXXsFq@~ou-z!9bHoM8*(hwl>X(zm)TDcdkF4lZm$1jP*HbnD`o1$g}_R#+bu2D zr%7Y8KdsaC-V*aem5#@*M%r^GPgu%P2e-BnBClhP2yoGFe40>);=}>{NONtkXQ01p z)OX^t2Ojhddot9eg0WTIVSTNBa}7V-^_pO595w|Hx9q?k4dMp@$G7PK*TD=y;ck6J zdGRB!_RAI2nR3%tO1IkdWp*bw*?<=pM_LZb30?!oK)s;En( z!#nnd9=cXJ<}+e{XLdx(q3&ikJISe?eSHHohk+pz+$6Cv{ytvc{QXmMn2XQ9U8rvt zrJdAn(0gpSD@N=yTrI_2^P#*zQg7MTp1)k(lv(*(KtUR6@M|2WB>2wRwC-h=wk6XF zPtSes*_JwI+^d>xW489MJw5R6=t5?{R zc|E8i?RL@p9)A3ZJAQOg`}+F;<_vnWA!KxR#g%jZ@y_1Qu#Uw)kFPw_xmZ?a^e*1{ zM|ImtqA|(CaDQ@Fyvcof`MN66&VI6m6gAyAXx`%cDx6BI{Bj#}V*Rn1(b~;Am)D2u zX7(027IO?Z2VYK^1vXXpoZ@AtH~N?0rYWwtyA15`6vEf6fk&;o-L;7zFt`5nk*iOy z`<918zB+k;EytI$FAXug)jk*e@e};4e9g__w4A5ev!!)H$yC@{?vsRqJ##X1R%xPG z&_R3oDi$MtTkVqfPj)HEUDx_7wd!y{8#1%$U*Dd0sK@=#6+!XlsE-s^1f5E`R9Wo71^b~mbVdU;Fw0LG~mUQg;xsX4QYRo3B@rH_=ry>DE8ef!c2ta8UcI#26# zF|`*4wtMHe@%#eGZw`#Yj|QWuB`eRD)b~)r9mM95p_JVG%-IdcbIX5qG#GpGD+IrS zEqxb1Rg&Dadk5#7t4j68I1f!@A$efp1?I%&d*56)yl!tkz!14<$0Od_&6cGw$WW0r zjSlQA7l*6;vgfhv!cR|RmAD$+w6j`rVf=-?-D@q>kOseUVSb*~jbAS^*1h?ZL)n(9 zDa}`4etXO6`}9;{k5E^N{rcfnV_(LPwsDg``wtyS*V<19c3!PGJ3Kqy9ksvkwbJ%Z z*N(fT0{e*Wji-Ck5!3YE0j|PZ@&z`v=kitWL$bqSt!e4bH!+(|Q)CZ30^nVPfkx{s zX{6of`p=BiPb@u@IyL!tRk>?qgBqCmo-Zlt!636g?z`s~zdfwuB7DXZHvV`Usp+%Z zo*&;Biu@MHE&2j+?j^o`Cr12u<>vOe=a&8a2hlcmFjJiDR>XnD4c4DAhZWCkiAgW{ E51q9-lK=n! literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/startIcon.png b/scenario/MusicPlayerOnline/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..366f76459ffd4494ec40d0ddd5c59385b9c5da11 GIT binary patch literal 4351 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 literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/base/profile/main_pages.json b/scenario/MusicPlayerOnline/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 00000000..1898d94f --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/en_US/element/string.json b/scenario/MusicPlayerOnline/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 00000000..9c7c1b7a --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "MusicPlayerOnline" + } + ] +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/main/resources/zh_CN/element/string.json b/scenario/MusicPlayerOnline/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 00000000..47b0f5d5 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "网络音乐" + } + ] +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/mock/mock-config.json5 b/scenario/MusicPlayerOnline/entry/src/mock/mock-config.json5 new file mode 100644 index 00000000..7a73a41b --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/Ability.test.ets b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 00000000..e5a54aeb --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/List.test.ets b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 00000000..cd611eb7 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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() { + abilityTest(); +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/TestAbility.ets b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 00000000..b4c21f7d --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + +export default class TestAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? ''); + let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator; + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); + let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs; + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments(); + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/pages/Index.ets b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 00000000..423b4276 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,17 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets new file mode 100644 index 00000000..d8cf0ef3 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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'; +import { BusinessError } from '@ohos.base'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import Want from '@ohos.app.ability.Want'; +import resourceManager from '@ohos.resourceManager'; +import util from '@ohos.util'; + +let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator; +let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs; +let jsonPath: string = 'mock/mock-config.json'; +let tag: string = 'testTag'; + +async function onAbilityCreateCallback(data: UIAbility) { + hilog.info(0x0000, 'testTag', 'onAbilityCreateCallback, data: ${}', JSON.stringify(data)); +} + +async function addAbilityMonitorCallback(err: BusinessError) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare'); + } + + async onRun() { + let tag = 'testTag'; + hilog.info(0x0000, tag, '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + let moduleName = abilityDelegatorArguments.parameters['-m']; + let context = abilityDelegator.getAppContext().getApplicationContext().createModuleContext(moduleName); + let mResourceManager = context.resourceManager; + await checkMock(abilityDelegator, mResourceManager); + const bundleName = abilityDelegatorArguments.bundleName; + const testAbilityName: string = 'TestAbility'; + let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + moduleName: moduleName + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + const want: Want = { + bundleName: bundleName, + abilityName: testAbilityName, + moduleName: moduleName + }; + abilityDelegator.startAbility(want, (err: BusinessError, data: void) => { + hilog.info(0x0000, tag, 'startAbility : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, tag, 'startAbility : data : %{public}s', JSON.stringify(data) ?? ''); + }) + hilog.info(0x0000, tag, '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} + +async function checkMock(abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator, resourceManager: resourceManager.ResourceManager) { + let rawFile: Uint8Array; + try { + rawFile = resourceManager.getRawFileContentSync(jsonPath); + hilog.info(0x0000, tag, 'MockList file exists'); + let mockStr: string = util.TextDecoder.create("utf-8", { ignoreBOM: true }).decodeWithStream(rawFile); + let mockMap: Record = getMockList(mockStr); + try { + abilityDelegator.setMockList(mockMap) + } catch (error) { + let code = (error as BusinessError).code; + let message = (error as BusinessError).message; + hilog.error(0x0000, tag, `abilityDelegator.setMockList failed, error code: ${code}, message: ${message}.`); + } + } catch (error) { + let code = (error as BusinessError).code; + let message = (error as BusinessError).message; + hilog.error(0x0000, tag, `ResourceManager:callback getRawFileContent failed, error code: ${code}, message: ${message}.`); + } +} + +function getMockList(jsonStr: string) { + let jsonObj: Record = JSON.parse(jsonStr); + let map: Map = new Map(Object.entries(jsonObj)); + let mockList: Record = {}; + map.forEach((value: object, key: string) => { + let realValue: string = value['source'].toString(); + mockList[key] = realValue; + }); + hilog.info(0x0000, tag, '%{public}s', 'mock-json value:' + JSON.stringify(mockList) ?? ''); + return mockList; +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/module.json5 b/scenario/MusicPlayerOnline/entry/src/ohosTest/module.json5 new file mode 100644 index 00000000..4fc97017 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/color.json b/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 00000000..3c712962 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/string.json b/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 00000000..65d8fa5a --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_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/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/media/icon.png b/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd45accb1dfd2fd0da16c732c72faa6e46b26521 GIT binary patch literal 2041 zcmaJ?c~nzZ9u6@;0AXaYAVN(;Kr(@>EJ+}skOWf=BA~*l4us@ELY9{%0m5QX6pnb} z(jZF|S&pLAS}3BZAfeQSvJ_h>F2Q1PYqi?o5`;m_yjZdG$1v}l_wK#F^L^iMz2}uD z#K$>1dON~kFlWvhW+Jp=tuN9J`ZlM-rl4h+ij|^D0y9;4JOuz-EdVnB6i3R-0ulk9 zApi4zAQA>!N9@-o026$1@L`d124`3G5<@_m`0f)Ug_Ie~;HT2q<_a=HH> zDwTdfD^-cW-|_xWVP$f@93UhDN-#&khZ>jZXLTi~$0`7x3REP6pk%&^2|`c>DutjN zMJD4Zs6Z}{FOpd;*mo2zm(GzXRXiCV;4m3zNCYnu3Fy=i5;2An&Lp!#LP;bRD~1&s z%VH6UY+}r6YDgG+p34OJIZ{BTn&%4s=CT&#TBkuOhdeU@g(w#guoa*b^)73=XyI65 z7Swys6)YS}?1EeZ6b!-I+yCnIya^g0>-NLsLWd8t56GZ_S3r|ZGbR+mV2ErEb9J)X zIF!njY-D-7{qtF2(?nlQ$0}!pzt=}hc*m%%)0Jb#N_K4@IC-`Pi5DahPZN7N9rH;ol;Gc*>-Go@gXKTM{eP)iJj6CYTIi}B#zLKZYD@_;m zrXmXXsFq@~ou-z!9bHoM8*(hwl>X(zm)TDcdkF4lZm$1jP*HbnD`o1$g}_R#+bu2D zr%7Y8KdsaC-V*aem5#@*M%r^GPgu%P2e-BnBClhP2yoGFe40>);=}>{NONtkXQ01p z)OX^t2Ojhddot9eg0WTIVSTNBa}7V-^_pO595w|Hx9q?k4dMp@$G7PK*TD=y;ck6J zdGRB!_RAI2nR3%tO1IkdWp*bw*?<=pM_LZb30?!oK)s;En( z!#nnd9=cXJ<}+e{XLdx(q3&ikJISe?eSHHohk+pz+$6Cv{ytvc{QXmMn2XQ9U8rvt zrJdAn(0gpSD@N=yTrI_2^P#*zQg7MTp1)k(lv(*(KtUR6@M|2WB>2wRwC-h=wk6XF zPtSes*_JwI+^d>xW489MJw5R6=t5?{R zc|E8i?RL@p9)A3ZJAQOg`}+F;<_vnWA!KxR#g%jZ@y_1Qu#Uw)kFPw_xmZ?a^e*1{ zM|ImtqA|(CaDQ@Fyvcof`MN66&VI6m6gAyAXx`%cDx6BI{Bj#}V*Rn1(b~;Am)D2u zX7(027IO?Z2VYK^1vXXpoZ@AtH~N?0rYWwtyA15`6vEf6fk&;o-L;7zFt`5nk*iOy z`<918zB+k;EytI$FAXug)jk*e@e};4e9g__w4A5ev!!)H$yC@{?vsRqJ##X1R%xPG z&_R3oDi$MtTkVqfPj)HEUDx_7wd!y{8#1%$U*Dd0sK@=#6+!XlsE-s^1f5E`R9Wo71^b~mbVdU;Fw0LG~mUQg;xsX4QYRo3B@rH_=ry>DE8ef!c2ta8UcI#26# zF|`*4wtMHe@%#eGZw`#Yj|QWuB`eRD)b~)r9mM95p_JVG%-IdcbIX5qG#GpGD+IrS zEqxb1Rg&Dadk5#7t4j68I1f!@A$efp1?I%&d*56)yl!tkz!14<$0Od_&6cGw$WW0r zjSlQA7l*6;vgfhv!cR|RmAD$+w6j`rVf=-?-D@q>kOseUVSb*~jbAS^*1h?ZL)n(9 zDa}`4etXO6`}9;{k5E^N{rcfnV_(LPwsDg``wtyS*V<19c3!PGJ3Kqy9ksvkwbJ%Z z*N(fT0{e*Wji-Ck5!3YE0j|PZ@&z`v=kitWL$bqSt!e4bH!+(|Q)CZ30^nVPfkx{s zX{6of`p=BiPb@u@IyL!tRk>?qgBqCmo-Zlt!636g?z`s~zdfwuB7DXZHvV`Usp+%Z zo*&;Biu@MHE&2j+?j^o`Cr12u<>vOe=a&8a2hlcmFjJiDR>XnD4c4DAhZWCkiAgW{ E51q9-lK=n! literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/profile/test_pages.json b/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 00000000..b7e7343c --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/scenario/MusicPlayerOnline/entry/src/test/List.test.ets b/scenario/MusicPlayerOnline/entry/src/test/List.test.ets new file mode 100644 index 00000000..907ed5b1 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/entry/src/test/LocalUnit.test.ets b/scenario/MusicPlayerOnline/entry/src/test/LocalUnit.test.ets new file mode 100644 index 00000000..5f657c69 --- /dev/null +++ b/scenario/MusicPlayerOnline/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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'; + +export default function localUnitTest() { + describe('localUnitTest',() => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/hvigor/hvigor-config.json5 b/scenario/MusicPlayerOnline/hvigor/hvigor-config.json5 new file mode 100644 index 00000000..721a37b2 --- /dev/null +++ b/scenario/MusicPlayerOnline/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "hvigorVersion": "3.2.4", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "3.2.4" + }, + "execution": { + // "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */ + } +} diff --git a/scenario/MusicPlayerOnline/hvigor/hvigor-wrapper.js b/scenario/MusicPlayerOnline/hvigor/hvigor-wrapper.js new file mode 100644 index 00000000..372eae8e --- /dev/null +++ b/scenario/MusicPlayerOnline/hvigor/hvigor-wrapper.js @@ -0,0 +1 @@ +"use strict";var u=require("path"),D=require("os"),e=require("fs"),t=require("crypto"),r=require("child_process"),n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},i={},C={},F=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(C,"__esModule",{value:!0}),C.maxPathLength=C.isMac=C.isLinux=C.isWindows=void 0;const E=F(D),A="Windows_NT",o="Darwin";function a(){return E.default.type()===A}function c(){return E.default.type()===o}C.isWindows=a,C.isLinux=function(){return"Linux"===E.default.type()},C.isMac=c,C.maxPathLength=function(){return c()?1016:a()?259:4095},function(e){var t=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),r=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),i=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&t(D,u,e);return r(D,u),D};Object.defineProperty(e,"__esModule",{value:!0}),e.WORK_SPACE=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.PROJECT_CACHES=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const F=i(D),E=i(u),A=C;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,A.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,A.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=E.resolve(F.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=E.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.PROJECT_CACHES="project_caches",e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=E.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=E.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=E.resolve(e.HVIGOR_USER_HOME,e.PROJECT_CACHES),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_WRAPPER_HOME=E.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.WORK_SPACE="workspace"}(i);var s={},l={};Object.defineProperty(l,"__esModule",{value:!0}),l.logInfoPrintConsole=l.logErrorAndExit=void 0,l.logErrorAndExit=function(u){u instanceof Error?console.error(u.message):console.error(u),process.exit(-1)},l.logInfoPrintConsole=function(u){console.log(u)};var B=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),d=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),f=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&B(D,u,e);return d(D,u),D};Object.defineProperty(s,"__esModule",{value:!0});var _=s.executeBuild=void 0;const p=f(e),O=f(u),h=l;_=s.executeBuild=function(u){const D=O.resolve(u,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const u=p.realpathSync(D);require(u)}catch(e){(0,h.logErrorAndExit)(`Error: ENOENT: no such file ${D},delete ${u} and retry.`)}};var P={},v={};!function(u){var D=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(u,"__esModule",{value:!0}),u.hashFile=u.hash=u.createHash=void 0;const r=D(t),i=D(e);u.createHash=(u="MD5")=>r.default.createHash(u);u.hash=(D,e)=>(0,u.createHash)(e).update(D).digest("hex");u.hashFile=(D,e)=>{if(i.default.existsSync(D))return(0,u.hash)(i.default.readFileSync(D,"utf-8"),e)}}(v);var g={},m={},R={};Object.defineProperty(R,"__esModule",{value:!0}),R.Unicode=void 0;class y{}R.Unicode=y,y.SPACE_SEPARATOR=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,y.ID_START=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,y.ID_CONTINUE=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(m,"__esModule",{value:!0}),m.JudgeUtil=void 0;const I=R;m.JudgeUtil=class{static isIgnoreChar(u){return"string"==typeof u&&("\t"===u||"\v"===u||"\f"===u||" "===u||" "===u||"\ufeff"===u||"\n"===u||"\r"===u||"\u2028"===u||"\u2029"===u)}static isSpaceSeparator(u){return"string"==typeof u&&I.Unicode.SPACE_SEPARATOR.test(u)}static isIdStartChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||I.Unicode.ID_START.test(u))}static isIdContinueChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||I.Unicode.ID_CONTINUE.test(u))}static isDigitWithoutZero(u){return/[1-9]/.test(u)}static isDigit(u){return"string"==typeof u&&/[0-9]/.test(u)}static isHexDigit(u){return"string"==typeof u&&/[0-9A-Fa-f]/.test(u)}};var N=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(g,"__esModule",{value:!0}),g.parseJsonText=g.parseJsonFile=void 0;const b=N(e),S=N(D),w=N(u),H=m;var x;!function(u){u[u.Char=0]="Char",u[u.EOF=1]="EOF",u[u.Identifier=2]="Identifier"}(x||(x={}));let M,T,V,G,j,J,W="start",U=[],L=0,$=1,k=0,K=!1,z="default",q="'",Z=1;function X(u,D=!1){T=String(u),W="start",U=[],L=0,$=1,k=0,G=void 0,K=D;do{M=Q(),nu[W]()}while("eof"!==M.type);return G}function Q(){for(z="default",j="",q="'",Z=1;;){J=Y();const u=Du[z]();if(u)return u}}function Y(){if(T[L])return String.fromCodePoint(T.codePointAt(L))}function uu(){const u=Y();return"\n"===u?($++,k=0):u?k+=u.length:k++,u&&(L+=u.length),u}g.parseJsonFile=function(u,D=!1,e="utf-8"){const t=b.default.readFileSync(w.default.resolve(u),{encoding:e});try{return X(t,D)}catch(D){if(D instanceof SyntaxError){const e=D.message.split("at");if(2===e.length)throw new Error(`${e[0].trim()}${S.default.EOL}\t at ${u}:${e[1].trim()}`)}throw new Error(`${u} is not in valid JSON/JSON5 format.`)}},g.parseJsonText=X;const Du={default(){switch(J){case"/":return uu(),void(z="comment");case void 0:return uu(),eu("eof")}if(!H.JudgeUtil.isIgnoreChar(J)&&!H.JudgeUtil.isSpaceSeparator(J))return Du[W]();uu()},start(){z="value"},beforePropertyName(){switch(J){case"$":case"_":return j=uu(),void(z="identifierName");case"\\":return uu(),void(z="identifierNameStartEscape");case"}":return eu("punctuator",uu());case'"':case"'":return q=J,uu(),void(z="string")}if(H.JudgeUtil.isIdStartChar(J))return j+=uu(),void(z="identifierName");throw Eu(x.Char,uu())},afterPropertyName(){if(":"===J)return eu("punctuator",uu());throw Eu(x.Char,uu())},beforePropertyValue(){z="value"},afterPropertyValue(){switch(J){case",":case"}":return eu("punctuator",uu())}throw Eu(x.Char,uu())},beforeArrayValue(){if("]"===J)return eu("punctuator",uu());z="value"},afterArrayValue(){switch(J){case",":case"]":return eu("punctuator",uu())}throw Eu(x.Char,uu())},end(){throw Eu(x.Char,uu())},comment(){switch(J){case"*":return uu(),void(z="multiLineComment");case"/":return uu(),void(z="singleLineComment")}throw Eu(x.Char,uu())},multiLineComment(){switch(J){case"*":return uu(),void(z="multiLineCommentAsterisk");case void 0:throw Eu(x.Char,uu())}uu()},multiLineCommentAsterisk(){switch(J){case"*":return void uu();case"/":return uu(),void(z="default");case void 0:throw Eu(x.Char,uu())}uu(),z="multiLineComment"},singleLineComment(){switch(J){case"\n":case"\r":case"\u2028":case"\u2029":return uu(),void(z="default");case void 0:return uu(),eu("eof")}uu()},value(){switch(J){case"{":case"[":return eu("punctuator",uu());case"n":return uu(),tu("ull"),eu("null",null);case"t":return uu(),tu("rue"),eu("boolean",!0);case"f":return uu(),tu("alse"),eu("boolean",!1);case"-":case"+":return"-"===uu()&&(Z=-1),void(z="numerical");case".":case"0":case"I":case"N":return void(z="numerical");case'"':case"'":return q=J,uu(),j="",void(z="string")}if(void 0===J||!H.JudgeUtil.isDigitWithoutZero(J))throw Eu(x.Char,uu());z="numerical"},numerical(){switch(J){case".":return j=uu(),void(z="decimalPointLeading");case"0":return j=uu(),void(z="zero");case"I":return uu(),tu("nfinity"),eu("numeric",Z*(1/0));case"N":return uu(),tu("aN"),eu("numeric",NaN)}if(void 0!==J&&H.JudgeUtil.isDigitWithoutZero(J))return j=uu(),void(z="decimalInteger");throw Eu(x.Char,uu())},zero(){switch(J){case".":case"e":case"E":return void(z="decimal");case"x":case"X":return j+=uu(),void(z="hexadecimal")}return eu("numeric",0)},decimalInteger(){switch(J){case".":case"e":case"E":return void(z="decimal")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimal(){switch(J){case".":j+=uu(),z="decimalFraction";break;case"e":case"E":j+=uu(),z="decimalExponent"}},decimalPointLeading(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalFraction");throw Eu(x.Char,uu())},decimalFraction(){switch(J){case"e":case"E":return j+=uu(),void(z="decimalExponent")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimalExponent(){switch(J){case"+":case"-":return j+=uu(),void(z="decimalExponentSign")}if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentSign(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentInteger(){if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},hexadecimal(){if(H.JudgeUtil.isHexDigit(J))return j+=uu(),void(z="hexadecimalInteger");throw Eu(x.Char,uu())},hexadecimalInteger(){if(!H.JudgeUtil.isHexDigit(J))return eu("numeric",Z*Number(j));j+=uu()},identifierNameStartEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":break;default:if(!H.JudgeUtil.isIdStartChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},identifierName(){switch(J){case"$":case"_":case"‌":case"‍":return void(j+=uu());case"\\":return uu(),void(z="identifierNameEscape")}if(!H.JudgeUtil.isIdContinueChar(J))return eu("identifier",j);j+=uu()},identifierNameEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":case"‌":case"‍":break;default:if(!H.JudgeUtil.isIdContinueChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},string(){switch(J){case"\\":return uu(),void(j+=function(){const u=Y(),D=function(){switch(Y()){case"b":return uu(),"\b";case"f":return uu(),"\f";case"n":return uu(),"\n";case"r":return uu(),"\r";case"t":return uu(),"\t";case"v":return uu(),"\v"}return}();if(D)return D;switch(u){case"0":if(uu(),H.JudgeUtil.isDigit(Y()))throw Eu(x.Char,uu());return"\0";case"x":return uu(),function(){let u="",D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());if(u+=uu(),D=Y(),!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());return u+=uu(),String.fromCodePoint(parseInt(u,16))}();case"u":return uu(),ru();case"\n":case"\u2028":case"\u2029":return uu(),"";case"\r":return uu(),"\n"===Y()&&uu(),""}if(void 0===u||H.JudgeUtil.isDigitWithoutZero(u))throw Eu(x.Char,uu());return uu()}());case'"':case"'":if(J===q){const u=eu("string",j);return uu(),u}return void(j+=uu());case"\n":case"\r":case void 0:throw Eu(x.Char,uu());case"\u2028":case"\u2029":!function(u){console.warn(`JSON5: '${Fu(u)}' in strings is not valid ECMAScript; consider escaping.`)}(J)}j+=uu()}};function eu(u,D){return{type:u,value:D,line:$,column:k}}function tu(u){for(const D of u){if(Y()!==D)throw Eu(x.Char,uu());uu()}}function ru(){let u="",D=4;for(;D-- >0;){const D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());u+=uu()}return String.fromCodePoint(parseInt(u,16))}const nu={start(){if("eof"===M.type)throw Eu(x.EOF);iu()},beforePropertyName(){switch(M.type){case"identifier":case"string":return V=M.value,void(W="afterPropertyName");case"punctuator":return void Cu();case"eof":throw Eu(x.EOF)}},afterPropertyName(){if("eof"===M.type)throw Eu(x.EOF);W="beforePropertyValue"},beforePropertyValue(){if("eof"===M.type)throw Eu(x.EOF);iu()},afterPropertyValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforePropertyName");case"}":Cu()}},beforeArrayValue(){if("eof"===M.type)throw Eu(x.EOF);"punctuator"!==M.type||"]"!==M.value?iu():Cu()},afterArrayValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforeArrayValue");case"]":Cu()}},end(){}};function iu(){const u=function(){let u;switch(M.type){case"punctuator":switch(M.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=M.value}return u}();if(K&&"object"==typeof u&&(u._line=$,u._column=k),void 0===G)G=u;else{const D=U[U.length-1];Array.isArray(D)?K&&"object"!=typeof u?D.push({value:u,_line:$,_column:k}):D.push(u):D[V]=K&&"object"!=typeof u?{value:u,_line:$,_column:k}:u}!function(u){if(u&&"object"==typeof u)U.push(u),W=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}}(u)}function Cu(){U.pop();const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}function Fu(u){const D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){const D=u.charCodeAt(0).toString(16);return`\\x${`00${D}`.substring(D.length)}`}return u}function Eu(u,D){let e="";switch(u){case x.Char:e=void 0===D?`JSON5: invalid end of input at ${$}:${k}`:`JSON5: invalid character '${Fu(D)}' at ${$}:${k}`;break;case x.EOF:e=`JSON5: invalid end of input at ${$}:${k}`;break;case x.Identifier:k-=5,e=`JSON5: invalid identifier character at ${$}:${k}`}const t=new Au(e);return t.lineNumber=$,t.columnNumber=k,t}class Au extends SyntaxError{}var ou={},au=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),cu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),su=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&au(D,u,e);return cu(D,u),D},lu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(ou,"__esModule",{value:!0}),ou.isFileExists=ou.offlinePluginConversion=ou.executeCommand=ou.getNpmPath=ou.hasNpmPackInPaths=void 0;const Bu=r,du=lu(e),fu=su(u),_u=i,pu=l;ou.hasNpmPackInPaths=function(u,D){try{return require.resolve(u,{paths:[...D]}),!0}catch(u){return!1}},ou.getNpmPath=function(){const u=process.execPath;return fu.join(fu.dirname(u),_u.NPM_TOOL)},ou.executeCommand=function(u,D,e){0!==(0,Bu.spawnSync)(u,D,e).status&&(0,pu.logErrorAndExit)(`Error: ${u} ${D} execute failed.See above for details.`)},ou.offlinePluginConversion=function(u,D){return D.startsWith("file:")||D.endsWith(".tgz")?fu.resolve(u,_u.HVIGOR,D.replace("file:","")):D},ou.isFileExists=function(u){return du.default.existsSync(u)&&du.default.statSync(u).isFile()};var Ou=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),hu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),Pu=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&Ou(D,u,e);return hu(D,u),D},vu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(P,"__esModule",{value:!0});var gu=P.initProjectWorkSpace=void 0;const mu=Pu(e),Ru=vu(D),yu=Pu(u),Iu=v,Nu=i,bu=g,Su=l,wu=ou;let Hu,xu,Mu;function Tu(u,D,e){return void 0!==e.dependencies&&(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,D.dependencies[u])===yu.normalize(e.dependencies[u])}function Vu(){const u=yu.join(Mu,Nu.WORK_SPACE);if((0,Su.logInfoPrintConsole)("Hvigor cleaning..."),!mu.existsSync(u))return;const D=mu.readdirSync(u);if(!D||0===D.length)return;const e=yu.resolve(Mu,"node_modules","@ohos","hvigor","bin","hvigor.js");mu.existsSync(e)&&(0,wu.executeCommand)(process.argv[0],[e,"--stop-daemon"],{});try{D.forEach((D=>{mu.rmSync(yu.resolve(u,D),{recursive:!0})}))}catch(D){(0,Su.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${u}.`)}}gu=P.initProjectWorkSpace=function(){if(Hu=function(){const u=yu.resolve(Nu.HVIGOR_PROJECT_WRAPPER_HOME,Nu.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);mu.existsSync(u)||(0,Su.logErrorAndExit)(`Error: Hvigor config file ${u} does not exist.`);return(0,bu.parseJsonFile)(u)}(),Mu=function(u){let D;D=function(u){let D=u.hvigorVersion;if(D.startsWith("file:")||D.endsWith(".tgz"))return!1;const e=u.dependencies,t=Object.getOwnPropertyNames(e);for(const u of t){const D=e[u];if(D.startsWith("file:")||D.endsWith(".tgz"))return!1}if(1===t.length&&"@ohos/hvigor-ohos-plugin"===t[0])return D>"2.5.0";return!1}(u)?function(u){let D=`${Nu.HVIGOR_ENGINE_PACKAGE_NAME}@${u.hvigorVersion}`;const e=u.dependencies;if(e){Object.getOwnPropertyNames(e).sort().forEach((u=>{D+=`,${u}@${e[u]}`}))}return(0,Iu.hash)(D)}(u):(0,Iu.hash)(process.cwd());return yu.resolve(Ru.default.homedir(),".hvigor","project_caches",D)}(Hu),xu=function(){const u=yu.resolve(Mu,Nu.WORK_SPACE,Nu.DEFAULT_PACKAGE_JSON);return mu.existsSync(u)?(0,bu.parseJsonFile)(u):{dependencies:{}}}(),!(0,wu.hasNpmPackInPaths)(Nu.HVIGOR_ENGINE_PACKAGE_NAME,[yu.join(Mu,Nu.WORK_SPACE)])||(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion)!==xu.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]||!function(){function u(u){const D=null==u?void 0:u.dependencies;return void 0===D?0:Object.getOwnPropertyNames(D).length}const D=u(Hu),e=u(xu);if(D+1!==e)return!1;for(const u in null==Hu?void 0:Hu.dependencies)if(!(0,wu.hasNpmPackInPaths)(u,[yu.join(Mu,Nu.WORK_SPACE)])||!Tu(u,Hu,xu))return!1;return!0}()){Vu();try{!function(){(0,Su.logInfoPrintConsole)("Hvigor installing...");for(const u in Hu.dependencies)Hu.dependencies[u]&&(Hu.dependencies[u]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.dependencies[u]));const u={dependencies:{...Hu.dependencies}};u.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion);const D=yu.join(Mu,Nu.WORK_SPACE);try{mu.mkdirSync(D,{recursive:!0});const e=yu.resolve(D,Nu.DEFAULT_PACKAGE_JSON);mu.writeFileSync(e,JSON.stringify(u))}catch(u){(0,Su.logErrorAndExit)(u)}(function(){const u=["config","set","store-dir",Nu.HVIGOR_PNPM_STORE_PATH],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)})(),function(){const u=["install"],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)}(),(0,Su.logInfoPrintConsole)("Hvigor install success.")}()}catch(u){Vu()}}return Mu};var Gu={};!function(t){var C=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),F=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),E=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&C(D,u,e);return F(D,u),D},A=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(t,"__esModule",{value:!0}),t.executeInstallPnpm=t.isPnpmInstalled=t.environmentHandler=t.checkNpmConifg=t.PNPM_VERSION=void 0;const o=r,a=E(e),c=A(D),s=E(u),B=i,d=l,f=ou;t.PNPM_VERSION="7.30.0",t.checkNpmConifg=function(){const u=s.resolve(B.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),D=s.resolve(c.default.homedir(),".npmrc");if((0,f.isFileExists)(u)||(0,f.isFileExists)(D))return;const e=(0,f.getNpmPath)(),t=(0,o.spawnSync)(e,["config","get","prefix"],{cwd:B.HVIGOR_PROJECT_ROOT_DIR});if(0!==t.status||!t.stdout)return void(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const r=s.resolve(`${t.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,f.isFileExists)(r)||(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},t.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},t.isPnpmInstalled=function(){return!!a.existsSync(B.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,f.hasNpmPackInPaths)("pnpm",[B.HVIGOR_WRAPPER_TOOLS_HOME])},t.executeInstallPnpm=function(){(0,d.logInfoPrintConsole)(`Installing pnpm@${t.PNPM_VERSION}...`);const u=(0,f.getNpmPath)();!function(){const u=s.resolve(B.HVIGOR_WRAPPER_TOOLS_HOME,B.DEFAULT_PACKAGE_JSON);try{a.existsSync(B.HVIGOR_WRAPPER_TOOLS_HOME)||a.mkdirSync(B.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const D={dependencies:{}};D.dependencies[B.PNPM]=t.PNPM_VERSION,a.writeFileSync(u,JSON.stringify(D))}catch(D){(0,d.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${u} failed.`)}}(),(0,f.executeCommand)(u,["install","pnpm"],{cwd:B.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,d.logInfoPrintConsole)("Pnpm install success.")}}(Gu),function(){Gu.checkNpmConifg(),Gu.environmentHandler(),Gu.isPnpmInstalled()||Gu.executeInstallPnpm();const D=gu();_(u.join(D,i.WORK_SPACE))}(); \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/hvigorfile.ts b/scenario/MusicPlayerOnline/hvigorfile.ts new file mode 100644 index 00000000..f3cb9f1a --- /dev/null +++ b/scenario/MusicPlayerOnline/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/scenario/MusicPlayerOnline/hvigorw b/scenario/MusicPlayerOnline/hvigorw new file mode 100644 index 00000000..4f0aa945 --- /dev/null +++ b/scenario/MusicPlayerOnline/hvigorw @@ -0,0 +1,54 @@ +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME="`pwd -P`" +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +#NODE_OPTS="--max-old-space-size=4096" + +fail() { + echo "$*" + exit 1 +} + +set_executable_node() { + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + + EXECUTABLE_NODE="${NODE_HOME}/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ]; then + set_executable_node +else + EXECUTABLE_NODE="node" + command -v ${EXECUTABLE_NODE} &> /dev/null || fail "ERROR: NODE_HOME not set and 'node' command not found" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ]; then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +if [ -z "${NODE_OPTS}" ]; then + NODE_OPTS="--" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" "${NODE_OPTS}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/scenario/MusicPlayerOnline/hvigorw.bat b/scenario/MusicPlayerOnline/hvigorw.bat new file mode 100644 index 00000000..b5eecf5a --- /dev/null +++ b/scenario/MusicPlayerOnline/hvigorw.bat @@ -0,0 +1,54 @@ +@rem +@rem ---------------------------------------------------------------------------- +@rem Hvigor startup script for Windows, version 1.0.0 +@rem +@rem Required ENV vars: +@rem ------------------ +@rem NODE_HOME - location of a Node home dir +@rem or +@rem Add %NODE_HOME%/bin to the PATH environment variable +@rem ---------------------------------------------------------------------------- +@rem +@echo off + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe +@rem set NODE_OPTS="--max-old-space-size=4096" + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +if not defined NODE_OPTS set NODE_OPTS="--" + +@rem Find node.exe +if defined NODE_HOME ( + set NODE_HOME=%NODE_HOME:"=% + set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% +) + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else if exist "%NODE_EXE_PATH%" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else ( + echo. + echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. + echo. + echo Please set the NODE_HOME variable in your environment to match the + echo location of your NodeJs installation. +) + +if "%ERRORLEVEL%" == "0" ( + if "%OS%" == "Windows_NT" endlocal +) else ( + exit /b %ERRORLEVEL% +) \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/oh-package-lock.json5 b/scenario/MusicPlayerOnline/oh-package-lock.json5 new file mode 100644 index 00000000..f2c0b4bc --- /dev/null +++ b/scenario/MusicPlayerOnline/oh-package-lock.json5 @@ -0,0 +1,21 @@ +{ + "lockfileVersion": 2, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.13": "@ohos/hypium@1.0.13" + }, + "packages": { + "@ohos/hypium@1.0.13": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.13.tgz", + "integrity": "sha512-d0+XvDeAYk5Vgl6JQ8Q1G+NPmTyJI8qgZ1PwPfcUbx/dfyKVAAv9lz1XtVNhYypyWEKqAzu8zMAC9GuHo2Y53Q==", + "registryType": "ohpm", + "shasum": "88d8dda420097efb98d770bf59616faef4682f06" + }, + "@ohos/hamock@1.0.0": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/scenario/MusicPlayerOnline/oh-package.json5 b/scenario/MusicPlayerOnline/oh-package.json5 new file mode 100644 index 00000000..4a9e1a1e --- /dev/null +++ b/scenario/MusicPlayerOnline/oh-package.json5 @@ -0,0 +1,14 @@ +{ + "name": "musicPlayerOnline", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.13", + "@ohos/hamock": "1.0.0" + } +} diff --git a/scenario/MusicPlayerOnline/screenshots/detail.jpeg b/scenario/MusicPlayerOnline/screenshots/detail.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..dd4a2af8b293b768dc279eb35fdbbd7c7ee23c95 GIT binary patch literal 41331 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 Z#*EBzsEPdV-#P!)9rZu#ed6Cg{|W8c`iTGl literal 0 HcmV?d00001 diff --git a/scenario/MusicPlayerOnline/screenshots/playlist.jpeg b/scenario/MusicPlayerOnline/screenshots/playlist.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..127035917a032117f4280a428b97e825c7150b17 GIT binary patch literal 60613 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%0DpIdFbCE|Bk8tJ+vFIDuI>El7Ek-EB(B8!(H1Cp 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 NKF9y0G1~9B{{>FLs(Szc literal 0 HcmV?d00001 diff --git a/scenario/MyMusic/build-profile.json5 b/scenario/MyMusic/build-profile.json5 index a4107014..1d76258e 100644 --- a/scenario/MyMusic/build-profile.json5 +++ b/scenario/MyMusic/build-profile.json5 @@ -4,13 +4,13 @@ { "name": "default", "material": { - "certpath": "C:\\Users\\Administrator\\.ohos\\config\\openharmony\\auto_ohos_default_MyMusic_com.example.myMusic.cer", - "storePassword": "0000001B089A7CB3265872A728E5F75B53883DE111A1CF89240C41BE5D6D363A4A03E0C91084D6F197AB4D", + "certpath": "C:/Users/Administrator/.ohos/config/openharmony/default_MyMusic_lkCEl5hB6byCgDNwkkzI0Yqu7GQgF9mylAcmfpHqqu0=.cer", + "storePassword": "0000001BC50E6AA7A047A3C1FC572B2EFF4332B1C55C5AD224EC264CE0DF65ECCB6F1D9FF06CF0102B2CDC", "keyAlias": "debugKey", - "keyPassword": "0000001B3FBC7F761895EDA1F71D82305EE49F3CB8544831DA0043E85787C852514AF21C6F95DA0E6C1F6C", - "profile": "C:\\Users\\Administrator\\.ohos\\config\\openharmony\\auto_ohos_default_MyMusic_com.example.myMusic.p7b", + "keyPassword": "0000001B3CCD1B99F4356696F09FA8A524C9FDDF1976231F98F425B8528E5BFE5DDE22A0ACE2F394CD5F09", + "profile": "C:/Users/Administrator/.ohos/config/openharmony/default_MyMusic_lkCEl5hB6byCgDNwkkzI0Yqu7GQgF9mylAcmfpHqqu0=.p7b", "signAlg": "SHA256withECDSA", - "storeFile": "C:\\Users\\Administrator\\.ohos\\config\\openharmony\\auto_ohos_default_MyMusic_com.example.myMusic.p12" + "storeFile": "C:/Users/Administrator/.ohos/config/openharmony/default_MyMusic_lkCEl5hB6byCgDNwkkzI0Yqu7GQgF9mylAcmfpHqqu0=.p12" } } ], diff --git a/scenario/MyMusic/hvigor/hvigor-config.json5 b/scenario/MyMusic/hvigor/hvigor-config.json5 index 1a474900..df8d324a 100644 --- a/scenario/MyMusic/hvigor/hvigor-config.json5 +++ b/scenario/MyMusic/hvigor/hvigor-config.json5 @@ -1,7 +1,7 @@ { - "hvigorVersion": "3.0.9", + "hvigorVersion": "3.2.4", "dependencies": { - "@ohos/hvigor-ohos-plugin": "3.0.9" + "@ohos/hvigor-ohos-plugin": "3.2.4" }, "execution": { // "daemon": true, /* Enable daemon compilation. Default: true */ @@ -15,4 +15,4 @@ "debugging": { // "stacktrace": false /* Disable stacktrace compilation. Default: false */ } -} +} \ No newline at end of file diff --git a/scenario/MyMusic/oh-package-lock.json5 b/scenario/MyMusic/oh-package-lock.json5 index ddc8a54d..b73134ed 100644 --- a/scenario/MyMusic/oh-package-lock.json5 +++ b/scenario/MyMusic/oh-package-lock.json5 @@ -1,5 +1,5 @@ { - "lockfileVersion": 1, + "lockfileVersion": 2, "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", "specifiers": { "@ohos/hypium@1.0.11": "@ohos/hypium@1.0.11" @@ -7,7 +7,9 @@ "packages": { "@ohos/hypium@1.0.11": { "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.11.tgz", - "integrity": "sha512-KawcLnv43C3QIYv1UbDnKCFX3MohtDxGuFvzlUxT/qf2DBilR56Ws6zrj90LdH6PjloJQwOPESuBQIHBACAK7w==" + "integrity": "sha512-KawcLnv43C3QIYv1UbDnKCFX3MohtDxGuFvzlUxT/qf2DBilR56Ws6zrj90LdH6PjloJQwOPESuBQIHBACAK7w==", + "registryType": "ohpm", + "shasum": "fa799d273fa7d921701578c5e7084849354a4af0" } } } \ No newline at end of file -- Gitee