From 5d64fa68c4b1d1f4df74c6d39479aa709c4eaac2 Mon Sep 17 00:00:00 2001 From: Hoshiiro Date: Mon, 10 Feb 2025 10:57:33 +0800 Subject: [PATCH] 1.2.0 --- AppScope/app.json5 | 4 +- CHANGELOG.md | 6 + README.md | 4 +- build-profile.json5 | 4 + entry/oh-package.json5 | 11 +- .../src/main/ets/ability/PLVEntryAbility.ets | 2 +- entry/src/main/ets/pages/PLVEntrancePage.ets | 62 ++ .../main/ets/pages/PLVLoginStreamerPage.ets | 293 ++++++ .../ets/startup/PLVMediaPlayerStartUp.ets | 4 +- .../main/resources/base/element/string.json | 44 + .../resources/base/media/plv_entrance_bg.png | Bin 0 -> 8983 bytes .../base/media/plv_entrance_live_bg.png | Bin 0 -> 43216 bytes .../base/media/plv_entrance_streamer_bg.png | Bin 0 -> 31356 bytes .../base/media/plv_login_input_delete.png | Bin 0 -> 264 bytes .../base/media/plv_login_password_hide.png | Bin 0 -> 1280 bytes .../base/media/plv_login_password_show.png | Bin 0 -> 2007 bytes .../base/media/plv_streamer_login_bg.png | Bin 0 -> 113055 bytes .../resources/base/profile/main_pages.json | 4 +- .../main/resources/en_US/element/string.json | 44 + .../main/resources/zh_CN/element/string.json | 44 + oh-package.json5 | 2 +- scenes_live/oh-package.json5 | 6 +- .../linkmic/PLVLILinkMicInvitationLayout.ets | 4 +- .../components/linkmic/PLVLILinkMicLayout.ets | 8 +- scenes_streamerAlone/.gitignore | 8 + scenes_streamerAlone/Index.ets | 4 + scenes_streamerAlone/build-profile.json5 | 28 + scenes_streamerAlone/hvigorfile.ts | 6 + scenes_streamerAlone/obfuscation-rules.txt | 21 + scenes_streamerAlone/oh-package.json5 | 13 + .../src/main/ets/PLVSAStreamerAlonePage.ets | 147 +++ .../src/main/ets/common/PLVSAPageDataBus.ets | 134 +++ .../ets/common/widget/PLVSAConfirmDialog.ets | 104 ++ .../common/widget/PLVSAPreferenceCardView.ets | 26 + .../chatroom/PLVSAChatroomLayout.ets | 124 +++ .../widget/PLVSAChatInputEntryView.ets | 60 ++ .../chatroom/widget/PLVSAChatInputView.ets | 349 +++++++ .../chatroom/widget/PLVSAChatListItem.ets | 789 +++++++++++++++ .../chatroom/widget/PLVSAChatListLayout.ets | 471 +++++++++ .../PLVSAChatOverLengthMessageDialog.ets | 198 ++++ .../chatroom/widget/PLVSAEventHub.ets | 15 + .../chatroom/widget/PLVSAFaceManager.ets | 59 ++ .../chatroom/widget/PLVSAGreetingView.ets | 93 ++ .../chatroom/widget/PLVSARewardBar.ets | 185 ++++ .../components/linkmic/PLVSALinkMicLayout.ets | 904 ++++++++++++++++++ .../linkmic/widgets/PLVSALinkMicButton.ets | 215 +++++ .../widgets/PLVSALinkMicInvitationLayout.ets | 208 ++++ .../PLVSALinkMicMemberControlDialog.ets | 574 +++++++++++ .../widgets/PLVSALinkMicViewerTimerLayout.ets | 38 + .../components/member/PLVSAMemberLayout.ets | 150 +++ .../member/item/PLVSAMemberListDataSource.ets | 38 + .../member/item/PLVSAMemberListItem.ets | 446 +++++++++ .../misc/PLVSANetworkDisconnectMaskLayout.ets | 132 +++ .../ets/components/more/PLVSAMoreLayout.ets | 316 ++++++ .../widgets/PLVSAMoreAllowLinkMicButton.ets | 52 + .../more/widgets/PLVSAMoreBitRateButton.ets | 62 ++ .../widgets/PLVSAMoreBitRateSelectLayout.ets | 247 +++++ .../widgets/PLVSAMoreCameraEnableButton.ets | 45 + .../widgets/PLVSAMoreCameraFacingButton.ets | 49 + .../widgets/PLVSAMoreCameraMirrorButton.ets | 57 ++ .../more/widgets/PLVSAMoreCloseRoomButton.ets | 41 + .../PLVSAMoreHangupAllLinkMicButton.ets | 53 + .../widgets/PLVSAMoreLinkMicSettingButton.ets | 34 + .../widgets/PLVSAMoreLinkMicSettingLayout.ets | 145 +++ .../PLVSAMoreMicrophoneEnableButton.ets | 39 + .../more/widgets/PLVSAMoreMixLayoutButton.ets | 33 + .../PLVSAMoreMixLayoutSelectLayout.ets | 244 +++++ .../widgets/PLVSAMoreOrientationButton.ets | 48 + .../widgets/PLVSAMorePushDowngradeButton.ets | 33 + .../widgets/PLVSAMorePushDowngradeLayout.ets | 226 +++++ .../PLVSAMoreResolutionRatioButton.ets | 55 ++ .../more/widgets/PLVSAMoreShareButton.ets | 32 + .../more/widgets/PLVSAMoreShareLayout.ets | 440 +++++++++ .../statusbar/PLVSAStatusBarLayout.ets | 236 +++++ .../widgets/PLVSAStatusChannelInfoBar.ets | 41 + .../widgets/PLVSAStatusChannelInfoLayout.ets | 237 +++++ .../widgets/PLVSAStatusMemberCountBar.ets | 166 ++++ .../widgets/PLVSAStatusNetworkBar.ets | 116 +++ .../widgets/PLVSAStatusNotificationBar.ets | 73 ++ .../PLVSAStatusPushDowngradeNotifyBar.ets | 78 ++ .../widgets/PLVSAStatusStreamDurationBar.ets | 67 ++ .../widgets/PLVSAStatusUserInfoBar.ets | 78 ++ .../components/toolbar/PLVSAToolBarLayout.ets | 32 + .../PLVSAToolBarLinkMicLayoutButton.ets | 52 + .../ets/layouts/end/PLVSALiveEndLayout.ets | 282 ++++++ .../main/ets/layouts/live/PLVSALiveLayout.ets | 203 ++++ .../layouts/startup/PLVSAStartUpLayout.ets | 357 +++++++ scenes_streamerAlone/src/main/module.json5 | 14 + .../main/resources/base/element/color.json | 8 + .../main/resources/base/element/string.json | 664 +++++++++++++ .../plvsa_chat_emotion_image_bar_icon.png | Bin 0 -> 3479 bytes .../media/plvsa_chat_input_emotion_icon.png | Bin 0 -> 970 bytes .../resources/base/media/plvsa_chat_msg.png | Bin 0 -> 742 bytes .../base/media/plvsa_chat_quiz_default.png | Bin 0 -> 867 bytes .../base/media/plvsa_chat_quiz_selected.png | Bin 0 -> 952 bytes .../plvsa_chat_quote_message_close_icon.png | Bin 0 -> 1359 bytes .../base/media/plvsa_chat_reward_bg.png | Bin 0 -> 4391 bytes .../media/plvsa_chat_reward_money_img.png | Bin 0 -> 9214 bytes .../media/plvsa_chat_select_image_icon.png | Bin 0 -> 600 bytes .../media/plvsa_chatroom_ban_chat_icon.png | Bin 0 -> 1277 bytes .../base/media/plvsa_chatroom_btn_like.png | Bin 0 -> 3525 bytes .../base/media/plvsa_chatroom_btn_like_1.png | Bin 0 -> 2279 bytes .../base/media/plvsa_chatroom_btn_like_10.png | Bin 0 -> 2358 bytes .../base/media/plvsa_chatroom_btn_like_2.png | Bin 0 -> 2572 bytes .../base/media/plvsa_chatroom_btn_like_3.png | Bin 0 -> 2554 bytes .../base/media/plvsa_chatroom_btn_like_4.png | Bin 0 -> 2594 bytes .../base/media/plvsa_chatroom_btn_like_5.png | Bin 0 -> 2787 bytes .../base/media/plvsa_chatroom_btn_like_6.png | Bin 0 -> 2345 bytes .../base/media/plvsa_chatroom_btn_like_7.png | Bin 0 -> 2225 bytes .../base/media/plvsa_chatroom_btn_like_8.png | Bin 0 -> 2286 bytes .../base/media/plvsa_chatroom_btn_like_9.png | Bin 0 -> 2293 bytes .../plvsa_chatroom_file_share_doc_icon.png | Bin 0 -> 1379 bytes .../plvsa_chatroom_file_share_pdf_icon.png | Bin 0 -> 1449 bytes .../plvsa_chatroom_file_share_ppt_icon.png | Bin 0 -> 833 bytes .../plvsa_chatroom_file_share_xls_icon.png | Bin 0 -> 1153 bytes .../media/plvsa_chatroom_red_pack_icon.png | Bin 0 -> 3764 bytes .../resources/base/media/plvsa_face_101.png | Bin 0 -> 6333 bytes .../resources/base/media/plvsa_face_102.png | Bin 0 -> 6158 bytes .../resources/base/media/plvsa_face_103.png | Bin 0 -> 6824 bytes .../resources/base/media/plvsa_face_104.png | Bin 0 -> 6740 bytes .../resources/base/media/plvsa_face_105.png | Bin 0 -> 6816 bytes .../resources/base/media/plvsa_face_106.png | Bin 0 -> 6999 bytes .../resources/base/media/plvsa_face_107.png | Bin 0 -> 6251 bytes .../resources/base/media/plvsa_face_108.png | Bin 0 -> 6180 bytes .../resources/base/media/plvsa_face_109.png | Bin 0 -> 6449 bytes .../resources/base/media/plvsa_face_110.png | Bin 0 -> 6525 bytes .../resources/base/media/plvsa_face_111.png | Bin 0 -> 7085 bytes .../resources/base/media/plvsa_face_112.png | Bin 0 -> 6744 bytes .../resources/base/media/plvsa_face_113.png | Bin 0 -> 5321 bytes .../resources/base/media/plvsa_face_114.png | Bin 0 -> 6714 bytes .../resources/base/media/plvsa_face_115.png | Bin 0 -> 6710 bytes .../resources/base/media/plvsa_face_116.png | Bin 0 -> 6336 bytes .../resources/base/media/plvsa_face_117.png | Bin 0 -> 6905 bytes .../resources/base/media/plvsa_face_118.png | Bin 0 -> 6957 bytes .../resources/base/media/plvsa_face_119.png | Bin 0 -> 6773 bytes .../resources/base/media/plvsa_face_120.png | Bin 0 -> 6463 bytes .../resources/base/media/plvsa_face_121.png | Bin 0 -> 6955 bytes .../resources/base/media/plvsa_face_122.png | Bin 0 -> 7042 bytes .../resources/base/media/plvsa_face_123.png | Bin 0 -> 6500 bytes .../resources/base/media/plvsa_face_124.png | Bin 0 -> 4149 bytes .../resources/base/media/plvsa_face_125.png | Bin 0 -> 3879 bytes .../resources/base/media/plvsa_face_126.png | Bin 0 -> 3476 bytes .../resources/base/media/plvsa_face_127.png | Bin 0 -> 5039 bytes .../resources/base/media/plvsa_face_128.png | Bin 0 -> 7782 bytes .../resources/base/media/plvsa_face_129.png | Bin 0 -> 7182 bytes .../resources/base/media/plvsa_face_130.png | Bin 0 -> 6106 bytes .../resources/base/media/plvsa_face_131.png | Bin 0 -> 4019 bytes .../resources/base/media/plvsa_face_132.png | Bin 0 -> 4686 bytes .../resources/base/media/plvsa_face_133.png | Bin 0 -> 4969 bytes .../resources/base/media/plvsa_face_134.png | Bin 0 -> 4454 bytes .../resources/base/media/plvsa_face_135.png | Bin 0 -> 8293 bytes .../resources/base/media/plvsa_face_136.png | Bin 0 -> 6063 bytes .../resources/base/media/plvsa_face_137.png | Bin 0 -> 4159 bytes .../resources/base/media/plvsa_face_138.png | Bin 0 -> 3644 bytes .../resources/base/media/plvsa_greet_bg.png | Bin 0 -> 8302 bytes .../resources/base/media/plvsa_img_site.png | Bin 0 -> 881 bytes .../plvsa_linkmic_audio_volume_closed.png | Bin 0 -> 457 bytes .../plvsa_linkmic_audio_volume_value_0.png | Bin 0 -> 363 bytes .../plvsa_linkmic_audio_volume_value_10.png | Bin 0 -> 380 bytes .../plvsa_linkmic_audio_volume_value_100.png | Bin 0 -> 402 bytes .../plvsa_linkmic_audio_volume_value_20.png | Bin 0 -> 392 bytes .../plvsa_linkmic_audio_volume_value_30.png | Bin 0 -> 388 bytes .../plvsa_linkmic_audio_volume_value_40.png | Bin 0 -> 400 bytes .../plvsa_linkmic_audio_volume_value_50.png | Bin 0 -> 406 bytes .../plvsa_linkmic_audio_volume_value_60.png | Bin 0 -> 402 bytes .../plvsa_linkmic_audio_volume_value_70.png | Bin 0 -> 396 bytes .../plvsa_linkmic_audio_volume_value_80.png | Bin 0 -> 402 bytes .../plvsa_linkmic_audio_volume_value_90.png | Bin 0 -> 392 bytes .../media/plvsa_linkmic_button_to_close.png | Bin 0 -> 854 bytes .../media/plvsa_linkmic_button_to_open.png | Bin 0 -> 2569 bytes .../plvsa_linkmic_fullscreen_exit_icon.png | Bin 0 -> 2138 bytes ..._linkmic_invitation_camera_closed_icon.png | Bin 0 -> 1566 bytes .../plvsa_linkmic_invitation_camera_icon.png | Bin 0 -> 514 bytes ...vsa_linkmic_invitation_microphone_icon.png | Bin 0 -> 641 bytes ...inkmic_invitation_only_audio_hint_icon.png | Bin 0 -> 8148 bytes ...linkmic_invitation_privacy_notify_icon.png | Bin 0 -> 1094 bytes .../media/plvsa_linkmic_item_speaker_icon.png | Bin 0 -> 1818 bytes .../plvsa_linkmic_layout_speaker_icon.png | Bin 0 -> 1792 bytes .../media/plvsa_linkmic_layout_tile_icon.png | Bin 0 -> 1868 bytes ...linkmic_member_control_fullscreen_icon.png | Bin 0 -> 848 bytes ...linkmic_member_control_hang_up_linkmic.png | Bin 0 -> 999 bytes .../media/plvsa_linkmic_new_request_icon.png | Bin 0 -> 1244 bytes .../plvsa_linkmic_no_stream_placeholder.png | Bin 0 -> 7526 bytes .../base/media/plvsa_linkmic_speaker_icon.png | Bin 0 -> 2036 bytes ...vsa_linkmic_video_disabled_placeholder.png | Bin 0 -> 514 bytes .../media/plvsa_linkmic_viewer_timer_icon.png | Bin 0 -> 469 bytes .../plvsa_linkmic_waiting_response_anim.webp | Bin 0 -> 5026 bytes .../plvsa_member_default_avatar_student.png | Bin 0 -> 2499 bytes .../plvsa_member_default_avatar_teacher.png | Bin 0 -> 4396 bytes .../base/media/plvsa_member_kick_out_icon.png | Bin 0 -> 1113 bytes .../plvsa_member_linkmic_hand_up_icon.png | Bin 0 -> 898 bytes .../plvsa_member_list_item_ban_chat_icon.png | Bin 0 -> 1395 bytes .../base/media/plvsa_member_more_icon.png | Bin 0 -> 1506 bytes ...plvsa_more_allow_viewer_linkmic_active.png | Bin 0 -> 1689 bytes ...vsa_more_allow_viewer_linkmic_inactive.png | Bin 0 -> 1743 bytes .../media/plvsa_more_bitrate_icon_high.png | Bin 0 -> 1305 bytes .../plvsa_more_bitrate_icon_standard.png | Bin 0 -> 1994 bytes .../media/plvsa_more_bitrate_icon_super.png | Bin 0 -> 1109 bytes .../plvsa_more_bitrate_icon_super_high.png | Bin 0 -> 1544 bytes .../base/media/plvsa_more_camera_disable.png | Bin 0 -> 1306 bytes .../base/media/plvsa_more_camera_enable.png | Bin 0 -> 959 bytes .../plvsa_more_camera_facing_disable.png | Bin 0 -> 1370 bytes .../media/plvsa_more_camera_facing_enable.png | Bin 0 -> 1381 bytes .../plvsa_more_camera_mirror_disable.png | Bin 0 -> 1069 bytes .../plvsa_more_camera_mirror_enable_off.png | Bin 0 -> 1089 bytes .../plvsa_more_camera_mirror_enable_on.png | Bin 0 -> 1078 bytes .../base/media/plvsa_more_close_room_icon.png | Bin 0 -> 1277 bytes ...plvsa_more_hang_up_viewer_linkmic_icon.png | Bin 0 -> 1031 bytes .../media/plvsa_more_linkmic_setting_icon.png | Bin 0 -> 1646 bytes .../media/plvsa_more_microphone_disable.png | Bin 0 -> 1752 bytes .../media/plvsa_more_microphone_enable.png | Bin 0 -> 1373 bytes .../base/media/plvsa_more_mix_layout_icon.png | Bin 0 -> 493 bytes .../media/plvsa_more_orientation_icon.png | Bin 0 -> 1572 bytes ...sa_more_push_downgrade_preference_icon.png | Bin 0 -> 1782 bytes .../plvsa_more_push_resolution_ratio_16_9.png | Bin 0 -> 852 bytes .../plvsa_more_push_resolution_ratio_4_3.png | Bin 0 -> 874 bytes ...plvsa_more_share_action_copy_link_icon.png | Bin 0 -> 1673 bytes ...lvsa_more_share_action_save_image_icon.png | Bin 0 -> 944 bytes .../base/media/plvsa_more_share_icon.png | Bin 0 -> 1060 bytes .../plvsa_network_disconnect_mask_icon.png | Bin 0 -> 2482 bytes .../media/plvsa_network_quality_good_icon.png | Bin 0 -> 142 bytes .../plvsa_network_quality_middle_icon.png | Bin 0 -> 140 bytes .../media/plvsa_network_quality_poor_icon.png | Bin 0 -> 141 bytes .../base/media/plvsa_popup_close.png | Bin 0 -> 276 bytes .../plvsa_preference_card_selected_icon.png | Bin 0 -> 1599 bytes .../base/media/plvsa_startup_back_icon.png | Bin 0 -> 3272 bytes .../plvsa_status_bar_channel_info_icon.png | Bin 0 -> 1244 bytes ...plvsa_status_bar_channel_info_nav_icon.png | Bin 0 -> 472 bytes .../base/media/plvsa_status_bar_close.png | Bin 0 -> 2602 bytes .../plvsa_status_bar_member_count_icon.png | Bin 0 -> 1105 bytes ...sa_status_bar_network_quality_bad_icon.png | Bin 0 -> 1104 bytes ...a_status_bar_network_quality_good_icon.png | Bin 0 -> 1212 bytes ...atus_bar_network_quality_moderate_icon.png | Bin 0 -> 1147 bytes ...r_push_downgrade_notify_bar_close_icon.png | Bin 0 -> 1066 bytes .../base/media/plvsa_streamer_finish_icon.png | Bin 0 -> 14226 bytes .../media/plvsa_streamer_page_bg_land.png | Bin 0 -> 126833 bytes .../media/plvsa_streamer_page_bg_port.png | Bin 0 -> 133790 bytes .../base/media/plvsa_tool_bar_member_icon.png | Bin 0 -> 2473 bytes .../media/plvsa_tool_bar_more_button_icon.png | Bin 0 -> 1727 bytes .../plvsa_tool_bar_product_control_icon.png | Bin 0 -> 3499 bytes .../resources/base/profile/main_pages.json | 5 + .../src/main/resources/en/element/string.json | 660 +++++++++++++ .../en/media/plvsa_chat_reward_money_img.png | Bin 0 -> 9214 bytes .../en/media/plvsa_red_pack_password_icon.png | Bin 0 -> 15361 bytes .../rawfile/plvsa_linkmic_invitation_bgm.mp3 | Bin 0 -> 408857 bytes .../src/main/resources/zh/element/string.json | 660 +++++++++++++ .../zh/media/plvsa_chat_quiz_default.png | Bin 0 -> 790 bytes .../zh/media/plvsa_chat_quiz_selected.png | Bin 0 -> 741 bytes .../zh/media/plvsa_chat_reward_money_img.png | Bin 0 -> 8158 bytes .../zh/media/plvsa_red_pack_password_icon.png | Bin 0 -> 12506 bytes 250 files changed, 12343 insertions(+), 22 deletions(-) create mode 100644 entry/src/main/ets/pages/PLVEntrancePage.ets create mode 100644 entry/src/main/ets/pages/PLVLoginStreamerPage.ets create mode 100644 entry/src/main/resources/base/media/plv_entrance_bg.png create mode 100644 entry/src/main/resources/base/media/plv_entrance_live_bg.png create mode 100644 entry/src/main/resources/base/media/plv_entrance_streamer_bg.png create mode 100644 entry/src/main/resources/base/media/plv_login_input_delete.png create mode 100644 entry/src/main/resources/base/media/plv_login_password_hide.png create mode 100644 entry/src/main/resources/base/media/plv_login_password_show.png create mode 100644 entry/src/main/resources/base/media/plv_streamer_login_bg.png create mode 100644 scenes_streamerAlone/.gitignore create mode 100644 scenes_streamerAlone/Index.ets create mode 100644 scenes_streamerAlone/build-profile.json5 create mode 100644 scenes_streamerAlone/hvigorfile.ts create mode 100644 scenes_streamerAlone/obfuscation-rules.txt create mode 100644 scenes_streamerAlone/oh-package.json5 create mode 100644 scenes_streamerAlone/src/main/ets/PLVSAStreamerAlonePage.ets create mode 100644 scenes_streamerAlone/src/main/ets/common/PLVSAPageDataBus.ets create mode 100644 scenes_streamerAlone/src/main/ets/common/widget/PLVSAConfirmDialog.ets create mode 100644 scenes_streamerAlone/src/main/ets/common/widget/PLVSAPreferenceCardView.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/PLVSAChatroomLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputEntryView.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputView.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListItem.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatOverLengthMessageDialog.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAEventHub.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAFaceManager.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAGreetingView.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSARewardBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/linkmic/PLVSALinkMicLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicInvitationLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicMemberControlDialog.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicViewerTimerLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/member/PLVSAMemberLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListDataSource.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListItem.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/misc/PLVSANetworkDisconnectMaskLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/PLVSAMoreLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreAllowLinkMicButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateSelectLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraEnableButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraFacingButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraMirrorButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCloseRoomButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreHangupAllLinkMicButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMicrophoneEnableButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutSelectLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreOrientationButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreResolutionRatioButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/PLVSAStatusBarLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusMemberCountBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNetworkBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNotificationBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusPushDowngradeNotifyBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusStreamDurationBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusUserInfoBar.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/toolbar/PLVSAToolBarLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/components/toolbar/widgets/PLVSAToolBarLinkMicLayoutButton.ets create mode 100644 scenes_streamerAlone/src/main/ets/layouts/end/PLVSALiveEndLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/layouts/live/PLVSALiveLayout.ets create mode 100644 scenes_streamerAlone/src/main/ets/layouts/startup/PLVSAStartUpLayout.ets create mode 100644 scenes_streamerAlone/src/main/module.json5 create mode 100644 scenes_streamerAlone/src/main/resources/base/element/color.json create mode 100644 scenes_streamerAlone/src/main/resources/base/element/string.json create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_emotion_image_bar_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_input_emotion_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_msg.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_quiz_default.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_quiz_selected.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_quote_message_close_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_reward_bg.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_reward_money_img.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_select_image_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_ban_chat_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_1.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_10.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_2.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_3.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_4.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_5.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_6.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_7.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_8.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_9.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_doc_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_pdf_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_ppt_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_xls_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_red_pack_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_101.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_102.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_103.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_104.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_105.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_106.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_107.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_108.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_109.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_110.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_111.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_112.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_113.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_114.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_115.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_116.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_117.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_118.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_119.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_120.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_121.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_122.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_123.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_124.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_125.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_126.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_127.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_128.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_129.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_130.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_131.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_132.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_133.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_134.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_135.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_136.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_137.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_face_138.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_greet_bg.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_img_site.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_closed.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_0.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_10.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_100.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_20.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_30.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_40.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_50.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_60.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_70.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_80.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_90.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_button_to_close.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_button_to_open.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_fullscreen_exit_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_camera_closed_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_camera_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_microphone_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_only_audio_hint_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_privacy_notify_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_item_speaker_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_layout_speaker_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_layout_tile_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_member_control_fullscreen_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_member_control_hang_up_linkmic.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_new_request_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_no_stream_placeholder.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_speaker_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_video_disabled_placeholder.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_viewer_timer_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_waiting_response_anim.webp create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_member_default_avatar_student.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_member_default_avatar_teacher.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_member_kick_out_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_member_linkmic_hand_up_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_member_list_item_ban_chat_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_member_more_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_allow_viewer_linkmic_active.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_allow_viewer_linkmic_inactive.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_high.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_standard.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_super.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_super_high.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_disable.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_enable.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_facing_disable.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_facing_enable.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_mirror_disable.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_mirror_enable_off.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_mirror_enable_on.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_close_room_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_hang_up_viewer_linkmic_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_linkmic_setting_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_microphone_disable.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_microphone_enable.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_mix_layout_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_orientation_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_push_downgrade_preference_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_push_resolution_ratio_16_9.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_push_resolution_ratio_4_3.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_share_action_copy_link_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_share_action_save_image_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_more_share_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_network_disconnect_mask_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_network_quality_good_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_network_quality_middle_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_network_quality_poor_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_popup_close.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_preference_card_selected_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_startup_back_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_channel_info_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_channel_info_nav_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_close.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_member_count_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_network_quality_bad_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_network_quality_good_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_network_quality_moderate_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_status_bar_push_downgrade_notify_bar_close_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_streamer_finish_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_streamer_page_bg_land.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_streamer_page_bg_port.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_tool_bar_member_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_tool_bar_more_button_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/media/plvsa_tool_bar_product_control_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/base/profile/main_pages.json create mode 100644 scenes_streamerAlone/src/main/resources/en/element/string.json create mode 100644 scenes_streamerAlone/src/main/resources/en/media/plvsa_chat_reward_money_img.png create mode 100644 scenes_streamerAlone/src/main/resources/en/media/plvsa_red_pack_password_icon.png create mode 100644 scenes_streamerAlone/src/main/resources/rawfile/plvsa_linkmic_invitation_bgm.mp3 create mode 100644 scenes_streamerAlone/src/main/resources/zh/element/string.json create mode 100644 scenes_streamerAlone/src/main/resources/zh/media/plvsa_chat_quiz_default.png create mode 100644 scenes_streamerAlone/src/main/resources/zh/media/plvsa_chat_quiz_selected.png create mode 100644 scenes_streamerAlone/src/main/resources/zh/media/plvsa_chat_reward_money_img.png create mode 100644 scenes_streamerAlone/src/main/resources/zh/media/plvsa_red_pack_password_icon.png diff --git a/AppScope/app.json5 b/AppScope/app.json5 index bcccf7e..d477576 100644 --- a/AppScope/app.json5 +++ b/AppScope/app.json5 @@ -1,8 +1,8 @@ { "app": { "bundleName": "net.plv.livescenes.demo", - "versionCode": 1010000, - "versionName": "1.1.0", + "versionCode": 1020000, + "versionName": "1.2.0", "icon": "$media:app_icon", "label": "$string:app_name" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 412ae00..a70ce92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [v1.2.0] - 2025-02-10 + +新增: + +1. 支持纯视频开播(当前仅部分频道支持) + ## [v1.1.0] - 2024-10-28 ### 【观看端场景】 diff --git a/README.md b/README.md index e9a3529..8219a10 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ polyv-harmony-livescenes-sdk-demo === [![build passing](https://img.shields.io/badge/build-passing-brightgreen.svg)](#) -[![GitHub release](https://img.shields.io/badge/release-1.1.0-blue.svg)](https://github.com/polyv/polyv-harmony-livescenes-sdk-demo/releases/tag/1.1.0) +[![GitHub release](https://img.shields.io/badge/release-1.2.0-blue.svg)](https://github.com/polyv/polyv-harmony-livescenes-sdk-demo/releases/tag/1.2.0) @@ -45,6 +45,6 @@ ohpm install @polyvharmony/live-scenes-sdk #### 3.1 集成文档 [集成文档](https://github.com/polyv/polyv-harmony-livescenes-sdk-demo/tree/master/publish/docs) #### 3.2 接口文档 -[v1.1.0 接口文档](https://repo.polyv.net/harmony/documents/livescenes_sdk/1.1.0/index.html) +[v1.2.0 接口文档](https://repo.polyv.net/harmony/documents/livescenes_sdk/1.2.0/index.html) #### 3.3 版本更新记录 [全版本更新记录](https://github.com/polyv/polyv-harmony-livescenes-sdk-demo/blob/master/CHANGELOG.md) diff --git a/build-profile.json5 b/build-profile.json5 index 9b97094..d263791 100644 --- a/build-profile.json5 +++ b/build-profile.json5 @@ -39,6 +39,10 @@ { "name": "scenes_live", "srcPath": "./scenes_live" + }, + { + "name": "scenes_streamerAlone", + "srcPath": "./scenes_streamerAlone" } ] } \ No newline at end of file diff --git a/entry/oh-package.json5 b/entry/oh-package.json5 index ec9138a..802bfc5 100644 --- a/entry/oh-package.json5 +++ b/entry/oh-package.json5 @@ -1,16 +1,17 @@ { "name": "entry", - "version": "1.1.0", + "version": "1.2.0", "description": "Please describe the basic information.", "main": "", "author": "", "license": "MIT", "dependencies": { "scenes_live": "file:../scenes_live", - "@polyvharmony/media-player-sdk": "2.3.1", - "@polyvharmony/media-player-core-ijk": "2.3.1", - "@polyvharmony/rtc-sdk": "1.0.0", - "@polyvharmony/rtc-core-artc": "4.4.0-p1", + "scenes_streamerAlone": "file:../scenes_streamerAlone", + "@polyvharmony/media-player-sdk": "2.4.0", + "@polyvharmony/media-player-core-ijk": "2.4.0", + "@polyvharmony/rtc-sdk": "1.1.0", + "@polyvharmony/rtc-core-artc": "1.1.0-v4.4.2", } } diff --git a/entry/src/main/ets/ability/PLVEntryAbility.ets b/entry/src/main/ets/ability/PLVEntryAbility.ets index 4bd2ab8..662257a 100644 --- a/entry/src/main/ets/ability/PLVEntryAbility.ets +++ b/entry/src/main/ets/ability/PLVEntryAbility.ets @@ -20,7 +20,7 @@ export default class PLVEntryAbility extends UIAbility { PLVLiveSceneSDK.init(this.context, windowStage) PLVMediaPlayerStartUp.start(this.context.getApplicationContext()) PLVRTCEngineStartUp.start() - windowStage.loadContent('pages/PLVLoginPage', (err) => { + windowStage.loadContent('pages/PLVEntrancePage', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; diff --git a/entry/src/main/ets/pages/PLVEntrancePage.ets b/entry/src/main/ets/pages/PLVEntrancePage.ets new file mode 100644 index 0000000..b999a2e --- /dev/null +++ b/entry/src/main/ets/pages/PLVEntrancePage.ets @@ -0,0 +1,62 @@ +import { router } from '@kit.ArkUI' + +@Entry +@Component +struct PLVEntrancePage { + build() { + Stack() { + Image($r('app.media.plv_entrance_bg')) + .objectFit(ImageFit.Cover) + .expandSafeArea() + + Column() { + LoginStreamerEntry() + LoginWatchEntry() + } + } + .width('100%') + .height('100%') + } +} + +@Component +struct LoginStreamerEntry { + build() { + Stack() { + Image($r('app.media.plv_entrance_streamer_bg')) + Text("手机开播") + .fontColor('#FFFFFF') + .fontSize(24) + .margin(36) + } + .alignContent(Alignment.TopStart) + .width(244) + .height(140) + .onClick(() => { + router.pushUrl({ + url: "pages/PLVLoginStreamerPage" + }) + }) + } +} + +@Component +struct LoginWatchEntry { + build() { + Stack() { + Image($r('app.media.plv_entrance_live_bg')) + Text("云直播观看") + .fontColor('#FFFFFF') + .fontSize(24) + .margin(36) + } + .alignContent(Alignment.TopStart) + .width(244) + .height(140) + .onClick(() => { + router.pushUrl({ + url: "pages/PLVLoginPage" + }) + }) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/PLVLoginStreamerPage.ets b/entry/src/main/ets/pages/PLVLoginStreamerPage.ets new file mode 100644 index 0000000..1395696 --- /dev/null +++ b/entry/src/main/ets/pages/PLVLoginStreamerPage.ets @@ -0,0 +1,293 @@ +import { + DerivedState, + isTextEmpty, + kvStore, + MutableState, + PLVKVStore, + MutableObserver, + runCatching, + RequirePermissions +} from '@polyvharmony/media-player-sdk' +import { PLVLiveSceneSDK, PLVToastUtils, PLVWebUtils } from 'scenes_live' +import { routerToStreamerAlone } from 'scenes_streamerAlone' +import { window } from '@kit.ArkUI' + +@Entry +@Component +struct PLVLoginStreamerPage { + private localChannelId: PLVKVStore = kvStore("plv_login_streamer_channel_id", String) + private localPassword: PLVKVStore = kvStore("plv_login_streamer_password", String) + private localNickname: PLVKVStore = kvStore("plv_login_streamer_nickname", String) + private localRememberPassword: PLVKVStore = kvStore("plv_login_streamer_remember_password", Boolean) + private localAgreeContract: PLVKVStore = kvStore("plv_login_streamer_agree_contract", Boolean) + private stateChannelId = new MutableState() + private statePassword = new MutableState() + private stateNickname = new MutableState() + private stateAgreeContract = new MutableState() + private stateLoginRequesting = new MutableState(false) + private stateLoginEnable = new DerivedState(() => { + return !isTextEmpty(this.stateChannelId.value) + && !isTextEmpty(this.statePassword.value) + && !this.stateLoginRequesting.value + }) + @State private arkChannelId: string = "" + @State private arkPassword: string = "" + @State private arkNickname: string = "" + @State private arkLoginEnable: boolean = true + @State private arkRememberPassword: boolean = false + @State private arkAgreeContract: boolean = false + private observers: MutableObserver[] = [] + + async aboutToAppear() { + this.stateChannelId.observe(it => this.arkChannelId = it).pushTo(this.observers) + this.statePassword.observe(it => this.arkPassword = it).pushTo(this.observers) + this.stateNickname.observe(it => this.arkNickname = it).pushTo(this.observers) + this.stateAgreeContract.observe(it => this.arkAgreeContract = it).pushTo(this.observers) + this.stateLoginEnable.observe(it => this.arkLoginEnable = it).pushTo(this.observers) + + this.stateChannelId.value = (await this.localChannelId.get())?.valueOf() ?? "" + this.statePassword.value = (await this.localPassword.get())?.valueOf() ?? "" + this.stateNickname.value = (await this.localNickname.get())?.valueOf() ?? "" + this.stateAgreeContract.value = (await this.localAgreeContract.get())?.valueOf() ?? false + this.arkRememberPassword = (await this.localRememberPassword.get())?.valueOf() ?? false + } + + async onPageShow() { + const windowInstance = await window.getLastWindow(getContext(this)) + windowInstance.setPreferredOrientation(window.Orientation.PORTRAIT) + } + + build() { + Stack() { + Image($r('app.media.plv_streamer_login_bg')) + .objectFit(ImageFit.Cover) + .expandSafeArea() + + Column() { + Text($r('app.string.plv_login_streamer_live_broadcast')) + .fontSize(30) + .fontColor('#F0F1F5') + .fontWeight(FontWeight.Bold) + .letterSpacing(4) + .margin({ + top: 36 + }) + + Column() { + TextInput({ + placeholder: $r('app.string.plv_login_streamer_enter_channel_number'), + text: this.arkChannelId + }) + .height(44) + .fontSize(14) + .fontColor('#F0F1F5') + .placeholderColor('#99F0F1F5') + .borderRadius(30) + .backgroundColor('#29FFFFFF') + .margin({ + top: 64 + }) + .stateStyles({ + focused: { + .borderColor('#4399FF') + .borderWidth(1) + } + }) + .cancelButton({ + style: CancelButtonStyle.INPUT, + icon: { + size: 12, + src: $r('app.media.plv_login_input_delete') + } + }) + .onChange(text => { + this.stateChannelId.value = text + }) + + TextInput({ + placeholder: $r('app.string.plv_login_streamer_enter_password'), + text: this.arkPassword + }) + .type(InputType.NEW_PASSWORD) + .height(44) + .fontSize(14) + .fontColor('#F0F1F5') + .placeholderColor('#99F0F1F5') + .borderRadius(30) + .backgroundColor('#29FFFFFF') + .margin({ + top: 16 + }) + .stateStyles({ + focused: { + .borderColor('#4399FF') + .borderWidth(1) + } + }) + .cancelButton({ + style: CancelButtonStyle.INPUT, + icon: { + size: 12, + src: $r('app.media.plv_login_input_delete') + } + }) + .passwordIcon({ + onIconSrc: $r('app.media.plv_login_password_show'), + offIconSrc: $r('app.media.plv_login_password_hide') + }) + .onChange(text => { + this.statePassword.value = text + }) + + TextInput({ + placeholder: $r('app.string.plv_login_streamer_enter_nickname'), + text: this.arkNickname + }) + .height(44) + .fontSize(14) + .fontColor('#F0F1F5') + .placeholderColor('#99F0F1F5') + .borderRadius(30) + .backgroundColor('#29FFFFFF') + .margin({ + top: 16 + }) + .stateStyles({ + focused: { + .borderColor('#4399FF') + .borderWidth(1) + } + }) + .cancelButton({ + style: CancelButtonStyle.INPUT, + icon: { + size: 12, + src: $r('app.media.plv_login_input_delete') + } + }) + .onChange(text => { + this.stateNickname.value = text + }) + + Button($r('app.string.plv_login_streamer_login')) + .width('100%') + .height(44) + .enabled(this.arkLoginEnable) + .fontColor('#F0F1F5') + .backgroundColor('#4399FF') + .borderRadius(30) + .margin({ + top: 64 + }) + .onClick(async () => { + const agreeContract = this.arkAgreeContract + if (!agreeContract) { + PLVToastUtils.shortShow($r('app.string.plv_login_streamer_check_the_agreement')) + return + } + this.stateLoginRequesting.value = true + const channelId = this.arkChannelId + const password = this.arkPassword + const nickname = this.arkNickname + const rememberPassword = this.arkRememberPassword + const sdk = PLVLiveSceneSDK.create() + const result = await runCatching(sdk.loginManager.loginStreamer(channelId, password, nickname)) + if (result.success === false) { + PLVToastUtils.shortShow(`loginStreamer error: ${result.error.message}`) + sdk.destroy() + } else { + if (rememberPassword) { + this.localChannelId.set(channelId) + this.localPassword.set(password) + this.localNickname.set(nickname) + } else { + this.localChannelId.set("") + this.localPassword.set("") + this.localNickname.set("") + } + this.localRememberPassword.set(rememberPassword) + this.gotoStreamerPage(sdk) + } + this.stateLoginRequesting.value = false + }) + } + .width('100%') + .padding({ + left: 40, + right: 40 + }) + + Row() { + Checkbox() + .width(16) + .height(16) + .select($$this.arkRememberPassword) + Text($r('app.string.plv_login_streamer_remember_password')) + .fontColor('#99F0F1F5') + .fontSize(12) + } + .width('100%') + .padding({ + left: 57 + }) + .margin({ + top: 19 + }) + + Row() { + Checkbox() + .width(16) + .height(16) + .select(this.arkAgreeContract) + .onChange(agree => { + this.stateAgreeContract.setValue(agree) + this.localAgreeContract.set(agree) + }) + Text($r('app.string.plv_login_streamer_read_and_agree')) + .fontColor('#99F0F1F5') + .fontSize(12) + Text($r('app.string.plv_login_streamer_privacy_policy')) + .fontColor('#F0F1F5') + .fontSize(12) + .onClick(() => this.gotoPrivacyPolicy()) + Text($r('app.string.plv_login_streamer_and')) + .fontColor('#99F0F1F5') + .fontSize(12) + Text($r('app.string.plv_login_streamer_user_agreement')) + .fontColor('#F0F1F5') + .fontSize(12) + .onClick(() => this.gotoUserAgreement()) + } + .width('100%') + .padding({ + left: 57 + }) + .margin({ + top: 5 + }) + } + .width('100%') + .height('100%') + } + .width('100%') + .height('100%') + } + + @RequirePermissions('ohos.permission.CAMERA', 'ohos.permission.MICROPHONE') + private gotoStreamerPage(sdk: PLVLiveSceneSDK) { + routerToStreamerAlone(sdk) + } + + private gotoPrivacyPolicy() { + PLVWebUtils.openWebLink('https://s2.videocc.net/app-simple-pages/privacy-policy/index.html') + } + + private gotoUserAgreement() { + PLVWebUtils.openWebLink('https://s2.videocc.net/app-simple-pages/user-agreement/index.html') + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/entry/src/main/ets/startup/PLVMediaPlayerStartUp.ets b/entry/src/main/ets/startup/PLVMediaPlayerStartUp.ets index 2a56abd..a120e51 100644 --- a/entry/src/main/ets/startup/PLVMediaPlayerStartUp.ets +++ b/entry/src/main/ets/startup/PLVMediaPlayerStartUp.ets @@ -5,7 +5,7 @@ import { PLVMediaPlayerAppContext, PLVMediaPlayerFactory, PLVMediaPlayerLogger, - safe + runCatching } from '@polyvharmony/media-player-sdk'; import { PLVMediaPlayerCoreIjkProvider } from '@polyvharmony/media-player-core-ijk'; import { Context } from '@ohos.abilityAccessCtrl'; @@ -65,7 +65,7 @@ class PLVKVStoreOhosImpl implements IPLVKVStore { await this.ensureKvStore() } - const result = await safe(this.kvStore?.get(key)) + const result = await runCatching(this.kvStore?.get(key)) if (result.success) { return result.data as string } else { diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index 9784f27..d01c8c7 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -12,6 +12,50 @@ "name": "EntryAbility_label", "value": "POLYV多场景" }, + { + "name": "plv_login_streamer_live_broadcast", + "value": "Mobile Live Broadcast" + }, + { + "name": "plv_login_streamer_enter_channel_number", + "value": "Please enter the channel number" + }, + { + "name": "plv_login_streamer_enter_password", + "value": "Please enter the password" + }, + { + "name": "plv_login_streamer_enter_nickname", + "value": "Please enter your nickname" + }, + { + "name": "plv_login_streamer_login", + "value": "Login" + }, + { + "name": "plv_login_streamer_remember_password", + "value": "Remember password" + }, + { + "name": "plv_login_streamer_read_and_agree", + "value": "I have read and agree to" + }, + { + "name": "plv_login_streamer_privacy_policy", + "value": " Privacy Policy " + }, + { + "name": "plv_login_streamer_and", + "value": "and" + }, + { + "name": "plv_login_streamer_user_agreement", + "value": " User Agreement " + }, + { + "name": "plv_login_streamer_check_the_agreement", + "value": "Please check the agreement" + }, { "name": "plv_permission_camera_reason", "value": "连麦场景需要使用摄像头" diff --git a/entry/src/main/resources/base/media/plv_entrance_bg.png b/entry/src/main/resources/base/media/plv_entrance_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..dc3fa676925094cbf6a7cf2fdef7ef3a045bae11 GIT binary patch literal 8983 zcmeHNc~nzZw@(O0)L5t#H4c^6QmjEmFXBigRvah+q6QEI5y=Gw!~tbcfkdfVi**bT z1c@RNnG_KL2f!)nWw2F2QB*1w6$HhJnS8%P{nqz~_O124_1ZVAvevox+eiWrG3?^ZEn@RZqs&awVmDCw{6h8L_&LE2c33pNh!;}3&*1hfyDs$03zHMpVx}fZKcVb;vYo_(v z``TZVns;h%G{4o}yW*l9x-z2q%Cf?)Buneylq*jn^Xe?MWy~DTg)$NVlgSsC#mskh4l}BE)?!NRmDe|{hH;VR;=*TlS*S^-ajPU609(iu# zyXza<8mz-QAEoARY>Nzha4}32`SP8bC)mss+hqnWSFjcH_+q|hnQ zUgSm#X^^-I`IGz#67efLu8Vm zvgdJP%SlGYsCklr5W+LO>32=)J2eNK`P(1}rtXycM#TZKGh!=zkBxUX@KfaAJ%Kan!qR3RTnh%sZh zAf6hm=1HrTs;FJ`k8%(%7lBx)ID}`{19(1$@u-4yC+>;SB?};Vv?C;M;w$8%eb=P% zq^>ck;5;AA2%T$B5u+BR^Q89+j=_?Iamg4G5KAPdAW6UIC{H@2V+L(p8lH&}7ee%? zg1U1L*g$8T*2M7hQi_dEy?>%uTp`55MXlV1dJrE1>bxEXYDaWo^70}qS( z>KcS=>k#wT0FjVdtBon0Yy7FnE3oIMYf#zvBPTUJqLkgk9+=9fX;4RW`m_;%cN*p4S5z-Wn z>zqkN#Ec^(-+f?aa6=P(IZ-Brv+QE1KSeBTi_c_aTlosMzJ;0>8aI#M>LG$qX>MN? zRpT|AF22YUaIU}lW#!%*ZwO;|a+dWoE0BE@dtYl($V_*FjBeW9%G9^m?Q zD}O{hviem80d(3ZG1m8Cs4rRV4E67bdSw~1c!;?lrmRyF7^}cK+7q+%8s31F34rr) zgm}F7EX=3&BfsC7^Z`OX1crnO$dii62@B|A)^SEyv0b3%*|@SZsG3AuS`|334BqFS zCaeASVF>cr3&j(MKylSFlDB6@A#XQN1XJ58l3QiSEw6u#(?O>gSqO6I^pu~m#!9S^ zGjX}dN3XmA2O)DRS?mSm`P^K{P?p0PH+x^?GwJFDSz*VDbA&o++hI5t_Y8iFvy&mn zA}~eW_x~O`L1fQF@;Lct#LvTy<2Rc&exA4(%Z=^KSKm!sN<2zPr3_BZ-2(P-xZstu z48$D+pCC|e-x8x5iQ(iqs_FpQY&O7~JJSAuB*qf4_SzZ@BN`tOqo>2@jH_F*D3?`X zAFEvdsewZNwWp<+uQ&8F8#r_VIW+Dy5$Ny~aj-~&z{i925Q56_2Efl@|2+O&-`R7? zM(me@{Qnec;$}e&l}s7KlZ`XYM}qH@VPuWYSVRkbB;5K++wCysda9at6rRaUNDj-37I`o^ml!p~H`j?K*P;6x-blC(k3;A4js3}`VMl-6bY8;G`{VC8^CzcdM~XqqUw~1pIjQ}**t`~-IQYkFmkWaQI$SW|f#Z>n9nP?yk9W=q%f-Jz}fVu(U+HvG^t#PX`2 zHZgmNLf-I6St5X1&|YCn%W@;3JADcg;6hB}3<#e1vgt5YtmSXL2ZT;khP;M&*PH(5 zfX~Yens9fE79cTVeF}-P2P+ZY!z28DY9f|0`LpH!MQ;2>YW_y+!zJ>^Df~BD zf1~wh?ZSWO*5A4H|1q~}D$IhcN0(6cjZ@pl%WP=I_jLG+ttl%yM+=Wo+LE$L{m%ns z?(}qJOGrumNS&pMHtA4PYeR#K(xj9r17A1_k5eNWXEr?1*`#R8neh2?*)n>1K0k^( z*SYR`^OA$?J&Lx$@s}NYo0z>m?=`BwL1yWdNh6C!?8+$ZeXjQqV>jje;6(Nz#rOfd z!)6PZjW4$9?os@Lν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

EiT)hffc#M12ExMn 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 CNot({ literal 0 HcmV?d00001 diff --git a/entry/src/main/resources/base/media/plv_login_password_hide.png b/entry/src/main/resources/base/media/plv_login_password_hide.png new file mode 100644 index 0000000000000000000000000000000000000000..86fbfada8ee03c2a90b40e15c7acfad1322b176d GIT binary patch literal 1280 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®4QDWh5xQw;$bvn5rJir}AStk>Tzw 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 EUrmfh@Bjb+ literal 0 HcmV?d00001 diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json index 57fe1cc..159cb2d 100644 --- a/entry/src/main/resources/base/profile/main_pages.json +++ b/entry/src/main/resources/base/profile/main_pages.json @@ -1,5 +1,7 @@ { "src": [ - "pages/PLVLoginPage" + "pages/PLVEntrancePage", + "pages/PLVLoginPage", + "pages/PLVLoginStreamerPage" ] } diff --git a/entry/src/main/resources/en_US/element/string.json b/entry/src/main/resources/en_US/element/string.json index b459da4..473f8e4 100644 --- a/entry/src/main/resources/en_US/element/string.json +++ b/entry/src/main/resources/en_US/element/string.json @@ -11,6 +11,50 @@ { "name": "EntryAbility_label", "value": "POLYV多场景" + }, + { + "name": "plv_login_streamer_live_broadcast", + "value": "Mobile Live Broadcast" + }, + { + "name": "plv_login_streamer_enter_channel_number", + "value": "Please enter the channel number" + }, + { + "name": "plv_login_streamer_enter_password", + "value": "Please enter the password" + }, + { + "name": "plv_login_streamer_enter_nickname", + "value": "Please enter your nickname" + }, + { + "name": "plv_login_streamer_login", + "value": "Login" + }, + { + "name": "plv_login_streamer_remember_password", + "value": "Remember password" + }, + { + "name": "plv_login_streamer_read_and_agree", + "value": "I have read and agree to" + }, + { + "name": "plv_login_streamer_privacy_policy", + "value": " Privacy Policy " + }, + { + "name": "plv_login_streamer_and", + "value": "and" + }, + { + "name": "plv_login_streamer_user_agreement", + "value": " User Agreement " + }, + { + "name": "plv_login_streamer_check_the_agreement", + "value": "Please check the agreement" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index 9293fba..1069610 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -11,6 +11,50 @@ { "name": "EntryAbility_label", "value": "POLYV多场景" + }, + { + "name": "plv_login_streamer_live_broadcast", + "value": "手机开播" + }, + { + "name": "plv_login_streamer_enter_channel_number", + "value": "请输入频道号" + }, + { + "name": "plv_login_streamer_enter_password", + "value": "请输入密码" + }, + { + "name": "plv_login_streamer_enter_nickname", + "value": "请输入昵称" + }, + { + "name": "plv_login_streamer_login", + "value": "登录" + }, + { + "name": "plv_login_streamer_remember_password", + "value": "记住密码" + }, + { + "name": "plv_login_streamer_read_and_agree", + "value": "已阅读并同意" + }, + { + "name": "plv_login_streamer_privacy_policy", + "value": "《隐私政策》" + }, + { + "name": "plv_login_streamer_and", + "value": "和" + }, + { + "name": "plv_login_streamer_user_agreement", + "value": "《使用协议》" + }, + { + "name": "plv_login_streamer_check_the_agreement", + "value": "请勾选协议" } ] } \ No newline at end of file diff --git a/oh-package.json5 b/oh-package.json5 index eea7360..5384a94 100644 --- a/oh-package.json5 +++ b/oh-package.json5 @@ -1,7 +1,7 @@ { "modelVersion": "5.0.0", "name": "@polyvharmony/harmony-livescenes-sdk", - "version": "1.1.0", + "version": "1.2.0", "description": "polyv harmony-livescenes-sdk", "main": "", "author": "", diff --git a/scenes_live/oh-package.json5 b/scenes_live/oh-package.json5 index ad196ee..db51424 100644 --- a/scenes_live/oh-package.json5 +++ b/scenes_live/oh-package.json5 @@ -1,13 +1,13 @@ { "name": "scenes_live", - "version": "1.1.0", + "version": "1.2.0", "description": "Please describe the basic information.", "main": "Index.ets", "author": "", "license": "MIT", "packageType": "InterfaceHar", "dependencies": { - "@polyvharmony/live-scenes-sdk": "1.1.0", - "@polyvharmony/media-player-sdk": "2.3.1" + "@polyvharmony/live-scenes-sdk": "1.2.0", + "@polyvharmony/media-player-sdk": "2.4.0" } } \ No newline at end of file diff --git a/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicInvitationLayout.ets b/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicInvitationLayout.ets index 7b2d69a..345f625 100644 --- a/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicInvitationLayout.ets +++ b/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicInvitationLayout.ets @@ -84,13 +84,13 @@ export struct PLVLILinkMicInvitationLayout { this.localViewer!.linkmicId, this.localViewer!.xcomponentId ) - this.sdk.linkmicManager.setVideoRender(param) + this.sdk.linkmicManager.setupVideoRender(param) }).onDestroy(() => { const param = new PLVLinkMicVideoRenderParam( this.localViewer!.linkmicId, null ) - this.sdk.linkmicManager.setVideoRender(param) + this.sdk.linkmicManager.removeVideoRender(param) }) } diff --git a/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicLayout.ets b/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicLayout.ets index b568879..d482f0f 100644 --- a/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicLayout.ets +++ b/scenes_live/src/main/ets/components/linkmic/PLVLILinkMicLayout.ets @@ -98,7 +98,9 @@ struct PLVLILinkMicViewerItemView { this.viewer.isVideoEnable.observe((videoEnable) => this.isVideoEnable = videoEnable).pushTo(this.observers) this.viewer.isAudioEnable.observe((audioEnable) => this.isAudioEnable = audioEnable).pushTo(this.observers) this.viewer.audioVolume.observe((audioVolume) => this.audioVolume = audioVolume).pushTo(this.observers) - this.viewerName = this.viewer.isMyself ? $r('app.string.plvli_chat_me', this.viewer.viewerName ?? "", "") : (this.viewer.viewerName ?? "") + this.viewer.viewerName.observe((viewerName) => { + this.viewerName = this.viewer.isMyself ? $r('app.string.plvli_chat_me', viewerName ?? "", "") : (viewerName ?? "") + }).pushTo(this.observers) if (this.viewer.isMyself) { this.sdk.linkmicManager.linkmicNetworkQuality.observe((networkQuality) => { this.networkQualityIcon = this.getNetworkQualityIcon(networkQuality) @@ -123,14 +125,14 @@ struct PLVLILinkMicViewerItemView { this.viewer.linkmicId, this.viewer.xcomponentId ) - this.sdk.linkmicManager.setVideoRender(renderParam) + this.sdk.linkmicManager.setupVideoRender(renderParam) }) .onDestroy(() => { const renderParam = new PLVLinkMicVideoRenderParam( this.viewer.linkmicId, null ) - this.sdk.linkmicManager.setVideoRender(renderParam) + this.sdk.linkmicManager.removeVideoRender(renderParam) }) } else { // 未开启摄像头占位图 diff --git a/scenes_streamerAlone/.gitignore b/scenes_streamerAlone/.gitignore new file mode 100644 index 0000000..745cc01 --- /dev/null +++ b/scenes_streamerAlone/.gitignore @@ -0,0 +1,8 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test +/oh-package-lock.json5 +BuildProfile.ets \ No newline at end of file diff --git a/scenes_streamerAlone/Index.ets b/scenes_streamerAlone/Index.ets new file mode 100644 index 0000000..79e9176 --- /dev/null +++ b/scenes_streamerAlone/Index.ets @@ -0,0 +1,4 @@ +export * from './src/main/ets/PLVSAStreamerAlonePage' + +// sdk +export * from '@polyvharmony/live-scenes-sdk' \ No newline at end of file diff --git a/scenes_streamerAlone/build-profile.json5 b/scenes_streamerAlone/build-profile.json5 new file mode 100644 index 0000000..e8a3c1d --- /dev/null +++ b/scenes_streamerAlone/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + }, + "consumerFiles": [ + "./obfuscation-rules.txt" + ] + } + }, + }, + ], + "targets": [ + { + "name": "default" + } + ] +} \ No newline at end of file diff --git a/scenes_streamerAlone/hvigorfile.ts b/scenes_streamerAlone/hvigorfile.ts new file mode 100644 index 0000000..4218707 --- /dev/null +++ b/scenes_streamerAlone/hvigorfile.ts @@ -0,0 +1,6 @@ +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/scenes_streamerAlone/obfuscation-rules.txt b/scenes_streamerAlone/obfuscation-rules.txt new file mode 100644 index 0000000..e978fdb --- /dev/null +++ b/scenes_streamerAlone/obfuscation-rules.txt @@ -0,0 +1,21 @@ +# 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 + +-keep-global-name +* \ No newline at end of file diff --git a/scenes_streamerAlone/oh-package.json5 b/scenes_streamerAlone/oh-package.json5 new file mode 100644 index 0000000..90761b2 --- /dev/null +++ b/scenes_streamerAlone/oh-package.json5 @@ -0,0 +1,13 @@ +{ + "name": "scenes_streamerAlone", + "version": "1.2.0", + "description": "Please describe the basic information.", + "main": "Index.ets", + "author": "", + "license": "MIT", + "packageType": "InterfaceHar", + "dependencies": { + "@polyvharmony/live-scenes-sdk": "1.2.0", + "@polyvharmony/media-player-sdk": "2.4.0" + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/PLVSAStreamerAlonePage.ets b/scenes_streamerAlone/src/main/ets/PLVSAStreamerAlonePage.ets new file mode 100644 index 0000000..1abf8dd --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/PLVSAStreamerAlonePage.ets @@ -0,0 +1,147 @@ +import { PLVLiveSceneSDK, PLVSocketStatus, PLVSocketStatusSup, PLVToastUtils } from '@polyvharmony/live-scenes-sdk'; +import { MutableObserver, requireNotNull } from '@polyvharmony/media-player-sdk'; +import { display, mediaquery, router, window } from '@kit.ArkUI'; +import { PLVSAPageDataBus, PLVSAStreamerStage } from './common/PLVSAPageDataBus'; +import { PLVSALinkMicFullScreenLayout, PLVSALinkMicLayout } from './components/linkmic/PLVSALinkMicLayout'; +import { PLVSAStartUpLayout } from './layouts/startup/PLVSAStartUpLayout'; +import { PLVSALiveLayout } from './layouts/live/PLVSALiveLayout'; +import { PLVSALiveEndLayout } from './layouts/end/PLVSALiveEndLayout'; +import { PLVSAConfirmDialog } from './common/widget/PLVSAConfirmDialog'; +import { common } from '@kit.AbilityKit'; + +const STREAMER_ALONE_PAGE_NAME = "PLVSAStreamerAlonePage" + +class StreamerAlonePayload { + readonly sdkId: number + + constructor(sdkId: number) { + this.sdkId = sdkId + } +} + +export function routerToStreamerAlone(sdk: PLVLiveSceneSDK) { + const param = new StreamerAlonePayload(sdk.uniqueId) + router.pushNamedRoute({ + name: STREAMER_ALONE_PAGE_NAME, + params: param + }) +} + +@Entry({ + routeName: STREAMER_ALONE_PAGE_NAME +}) +@Component +struct PLVSAStreamerAlonePage { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = requireNotNull(PLVLiveSceneSDK.get((router.getParams() as StreamerAlonePayload).sdkId)) + @Provide('pageDataBus') pageDataBus: PLVSAPageDataBus = new PLVSAPageDataBus() + @State stage: PLVSAStreamerStage = PLVSAStreamerStage.STARTUP + @State isPortrait: boolean = true + private exitDialogController: CustomDialogController | null = null + private readonly queryOrientation = mediaquery.matchMediaSync('(orientation: landscape)'); + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.setKeepScreenOn(true) + this.sdk.initData(getContext() as common.UIAbilityContext) + this.loginSocket() + this.queryOrientation.on("change", () => { + this.updateOrientation() + }) + this.pageDataBus.recoverSetting.channelId = this.sdk.channelData.loginChannelId + this.pageDataBus.streamerStage.observe(it => this.stage = it).pushTo(this.observers) + this.pageDataBus.isPortrait.observe(it => this.isPortrait = it).pushTo(this.observers) + } + + build() { + Stack() { + Image(this.isPortrait ? $r('app.media.plvsa_streamer_page_bg_port') : $r('app.media.plvsa_streamer_page_bg_land')) + .width('100%') + .height('100%') + .objectFit(ImageFit.Cover) + + PLVSALinkMicLayout() + + if (this.stage === PLVSAStreamerStage.STARTUP) { + PLVSAStartUpLayout() + } else if (this.stage === PLVSAStreamerStage.LIVE) { + PLVSALiveLayout() + .hitTestBehavior(HitTestMode.Transparent) + } else if (this.stage === PLVSAStreamerStage.END) { + PLVSALiveEndLayout() + } + + PLVSALinkMicFullScreenLayout() + } + } + + private loginSocket() { + this.sdk.socketManager.onStatus((status: PLVSocketStatusSup) => { + switch (status.socketStatus) { + case PLVSocketStatus.RECONNECTING: + PLVToastUtils.shortShow($r('app.string.plvsa_chat_toast_reconnecting')) + break; + case PLVSocketStatus.RECONNECT_SUCCESS: + PLVToastUtils.shortShow($r('app.string.plvsa_chat_toast_reconnect_success')) + break; + case PLVSocketStatus.LOGIN_FAIL: + getContext().resourceManager.getStringValue($r('app.string.plvsa_chat_toast_login_failed')) + .then((value) => { + PLVToastUtils.shortShow(`${value}: message=${status.error?.message}`) + }) + break; + case PLVSocketStatus.BE_KICKED_OUT: + this.exitWithDialog($r('app.string.plvsa_chat_toast_been_kicked')) + break + case PLVSocketStatus.LOGIN_REFUSE: + this.exitWithDialog($r('app.string.plvsa_chat_toast_been_kicked')) + break + case PLVSocketStatus.LOGIN_ELSEWHERE: + this.exitWithDialog($r('app.string.plvsa_chat_toast_account_login_elsewhere')) + break + default: + break; + } + }, this) + this.sdk?.socketManager.login() + } + + private exitWithDialog(content: string | Resource) { + this.sdk.linkmicManager.leaveLinkMic() + this.sdk.streamerManager.finishStream() + this.exitDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + content: content, + hasCancel: false, + onClickConfirm: (controller) => { + this.pageDataBus.finishStream(this.sdk) + controller?.close() + } + }), + autoCancel: false, + customStyle: true + }) + this.exitDialogController.open() + } + + private updateOrientation() { + const orientation = display.getDefaultDisplaySync().orientation + this.pageDataBus.isPortrait.value = orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } + + onBackPress(): boolean | void { + return this.pageDataBus.onBackPressHandler.onBackPress() + } + + aboutToDisappear(): void { + this.setKeepScreenOn(false) + this.queryOrientation.off("change") + MutableObserver.disposeAll(this.observers) + this.observers = [] + this.sdk.destroy() + } + + private async setKeepScreenOn(keepScreenOn: boolean) { + const lastWindow = await window.getLastWindow(getContext(this)); + lastWindow.setWindowKeepScreenOn(keepScreenOn); + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/common/PLVSAPageDataBus.ets b/scenes_streamerAlone/src/main/ets/common/PLVSAPageDataBus.ets new file mode 100644 index 0000000..1f5ad59 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/common/PLVSAPageDataBus.ets @@ -0,0 +1,134 @@ +import { + PLVLinkMicCameraFacing, + PLVLinkMicViewer, + PLVLiveSceneSDK, + PLVPushOrientation +} from '@polyvharmony/live-scenes-sdk'; +import { + MutableState, + OnBackPressHandler, + PLVKVStore, + RecursivePartial, + requireNotNull +} from '@polyvharmony/media-player-sdk'; +import { PLVSALinkMicLayoutType } from '../components/linkmic/PLVSALinkMicLayout'; +import { window } from '@kit.ArkUI'; + +export class PLVSAPageDataBus { + /** + * 当前直播界面阶段 + */ + readonly streamerStage = new MutableState(PLVSAStreamerStage.STARTUP) + /** + * 本地观看的连麦画面布局 + */ + readonly linkmicLayoutType = new MutableState(PLVSALinkMicLayoutType.TILE) + /** + * 连麦全屏显示的观众 + */ + readonly linkmicFullScreenViewer = new MutableState(null) + /** + * 成员列表布局是否正在显示 + */ + readonly memberLayoutVisible = new MutableState(false) + /** + * 断网遮罩是否显示 + */ + readonly networkDisconnectedMaskVisible = new MutableState(false) + /** + * 是否竖屏 + */ + readonly isPortrait = new MutableState(true) + /** + * 返回回调 + */ + readonly onBackPressHandler = new OnBackPressHandler() + /** + * 保存直播的部分配置,用于直播中途异常退出时恢复为上次配置状态 + */ + readonly recoverSetting = new PLVSAStreamerRecoverSetting() + + finishStream(sdk: PLVLiveSceneSDK) { + sdk.streamerManager.finishStream() + sdk.linkmicManager.enableCamera(false) + sdk.linkmicManager.enableMicrophone(false) + this.streamerStage.setValue(PLVSAStreamerStage.END) + } +} + +export enum PLVSAStreamerStage { + /** + * 开始前准备阶段 + */ + STARTUP, + /** + * 直播中 + */ + LIVE, + /** + * 直播结束 + */ + END +} + +export class PLVSAStreamerRecoverSetting { + channelId?: string + isPortrait?: boolean + bitRateIndex?: number + isEnableCamera?: boolean + isFrontCamera?: boolean + + async recoverFromLocal(sdk: PLVLiveSceneSDK) { + this.channelId = requireNotNull(sdk.channelData.loginChannelId) + const setting = await this.kvStore.get() + if (setting === undefined) { + return + } + this.updateValue(setting) + + if (this.isPortrait !== undefined) { + const windowInstance = await window.getLastWindow(getContext()) + windowInstance.setPreferredOrientation(this.isPortrait ? window.Orientation.PORTRAIT : window.Orientation.LANDSCAPE) + sdk.streamerManager.setPushOrientation(this.isPortrait ? PLVPushOrientation.PORTRAIT : PLVPushOrientation.LANDSCAPE) + } + if (this.bitRateIndex !== undefined) { + const targetBitRate = (sdk.streamerManager.channelSupportBitRateEncodeParams.value ?? []) + .find(it => it.bitRate.index === this.bitRateIndex) + if (targetBitRate !== undefined) { + sdk.streamerManager.setBitRate(targetBitRate.bitRate) + } + } + if (this.isEnableCamera !== undefined) { + sdk.linkmicManager.enableCamera(this.isEnableCamera) + } + if (this.isFrontCamera !== undefined) { + const currentFacingFront = sdk.linkmicManager.cameraFacing.value !== PLVLinkMicCameraFacing.BACK + if (currentFacingFront !== this.isFrontCamera) { + sdk.linkmicManager.switchCamera() + } + } + } + + update(partial: RecursivePartial) { + this.updateValue(partial) + this.saveToLocal() + } + + private updateValue(partial: RecursivePartial) { + this.channelId = partial.channelId ?? this.channelId + this.isPortrait = partial.isPortrait ?? this.isPortrait + this.bitRateIndex = partial.bitRateIndex ?? this.bitRateIndex + this.isEnableCamera = partial.isEnableCamera ?? this.isEnableCamera + this.isFrontCamera = partial.isFrontCamera ?? this.isFrontCamera + } + + private async saveToLocal() { + if (this.channelId !== undefined) { + await this.kvStore.set(this) + } + } + + private get kvStore() { + return new PLVKVStore(`plvsa_streamer_recover_setting_${requireNotNull(this.channelId)}`, PLVSAStreamerRecoverSetting) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/common/widget/PLVSAConfirmDialog.ets b/scenes_streamerAlone/src/main/ets/common/widget/PLVSAConfirmDialog.ets new file mode 100644 index 0000000..b24ca2e --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/common/widget/PLVSAConfirmDialog.ets @@ -0,0 +1,104 @@ +import { lateInit } from '@polyvharmony/media-player-sdk'; + +@CustomDialog +export struct PLVSAConfirmDialog { + controller?: CustomDialogController = lateInit() + hasTitle: boolean = true + title: string | Resource = $r('app.string.plvsa_confirm_dialog_title') + hasContent: boolean = true + content: string | Resource = $r('app.string.plvsa_confirm_dialog_content') + hasConfirm: boolean = true + confirmText: string | Resource = $r('app.string.plvsa_confirm_dialog_confirm') + hasCancel: boolean = true + cancelText: string | Resource = $r('app.string.plvsa_confirm_dialog_cancel') + onClickConfirm: (controller: CustomDialogController | undefined) => void = (controller) => { + controller?.close() + } + onClickCancel: (controller: CustomDialogController | undefined) => void = (controller) => { + controller?.close() + } + + build() { + Column() { + if (this.hasTitle) { + Text(this.title) + .fontColor('#FFFFFF') + .fontWeight(FontWeight.Bold) + .fontSize(18) + .textAlign(TextAlign.Center) + } + + if (this.hasContent) { + Text(this.content) + .fontColor('#BFFFFFFF') + .fontSize(14) + .textAlign(TextAlign.Center) + .margin({ + top: 12 + }) + } + + Row() { + if (this.hasCancel) { + Text(this.cancelText) + .layoutWeight(1) + .fontColor('#0382FF') + .fontSize(14) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + .borderRadius(18) + .borderColor('#0080FF') + .borderWidth(1) + .padding({ + top: 11, + bottom: 11 + }) + .onClick(() => { + this.onClickCancel(this.controller) + }) + } + if (this.hasCancel && this.hasConfirm) { + Blank() + .width(10) + } + if (this.hasConfirm) { + Text(this.confirmText) + .layoutWeight(1) + .fontColor('#FFFFFF') + .fontSize(14) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: [ + ['#0080FF', 0], + ['#3399FF', 0] + ] + }) + .padding({ + top: 11, + bottom: 11 + }) + .onClick(() => { + this.onClickConfirm(this.controller) + }) + } + } + .width('100%') + .margin({ + top: 25 + }) + } + .width(260) + .backgroundColor('#2C2C2C') + .borderRadius(16) + .padding({ + left: 24, + right: 24, + top: 20, + bottom: 18 + }) + + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/common/widget/PLVSAPreferenceCardView.ets b/scenes_streamerAlone/src/main/ets/common/widget/PLVSAPreferenceCardView.ets new file mode 100644 index 0000000..11d311a --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/common/widget/PLVSAPreferenceCardView.ets @@ -0,0 +1,26 @@ +@Component +export struct PLVSAPreferenceCardView { + @BuilderParam slot: () => void = this.noopSlot + @Prop selected: boolean = false + + build() { + Stack() { + if (this.selected) { + Image($r("app.media.plvsa_preference_card_selected_icon")) + .width(28) + .height(32) + } + this.slot() + } + .alignContent(Alignment.BottomEnd) + .borderWidth(1) + .borderColor(this.selected ? '#4399FF' : 'transparent') + .borderRadius(8) + .backgroundColor('#0AF0F1F5') + } + + @Builder + noopSlot() { + + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/PLVSAChatroomLayout.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/PLVSAChatroomLayout.ets new file mode 100644 index 0000000..b97d290 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/PLVSAChatroomLayout.ets @@ -0,0 +1,124 @@ +import { + PLVBaseIdEvent, + PLVChannelData, + PLVChatQuoteDataBean, + PLVCommonConstants, + PLVLazyDataSource, + PLVLiveSceneSDK +} from '@polyvharmony/live-scenes-sdk' +import { PLVSAChatInputEntryView } from './widget/PLVSAChatInputEntryView' +import { PLVSAChatInputView } from './widget/PLVSAChatInputView' +import { PLVSAChatListLayout } from './widget/PLVSAChatListLayout' +import { PLVSAEventHub } from './widget/PLVSAEventHub' +import { PLVSAGreetingView } from './widget/PLVSAGreetingView' +import { PLVSARewardBar } from './widget/PLVSARewardBar' + +@Component +export struct PLVSAChatroomLayout { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + private chatListScroller: ListScroller = new ListScroller() + @State private isQuizSelected: boolean = false + @State private isShowChatInputLayout: boolean = false + @State private isFocusModeOpen: boolean = false + @State private isCloseRoom: boolean = false + @State private quizMenu: undefined = undefined + @State private fullChatListData: PLVLazyDataSource = new PLVLazyDataSource() + @State private quizListData: PLVLazyDataSource = new PLVLazyDataSource() + @State private reply: PLVChatQuoteDataBean | undefined = undefined + + aboutToAppear() { + this.channelData = this.sdk?.channelData + this.onReplyData() + } + + build() { + RelativeContainer() { + PLVSAChatListLayout({ + isQuizSelected: this.isQuizSelected, + isFocusModeOpen: this.isFocusModeOpen, + quizMenu: this.quizMenu, + fullChatListData: this.fullChatListData, + chatListScroller: this.chatListScroller, + quizListData: this.quizListData, + }) + .id('plvsa_chatroom_list_layout') + .width(244) + .height(152) + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + bottom: { anchor: 'plvsa_chatroom_input_entry_layout', align: VerticalAlign.Top } + }) + .margin({ + left: 8, + bottom: 16 + }) + + PLVSAChatInputEntryView({ + isQuizSelected: this.isQuizSelected, + isShowChatInputLayout: this.isShowChatInputLayout, + quizMenu: this.quizMenu, + isCloseRoom: this.isCloseRoom, + isFocusModeOpen: this.isFocusModeOpen + }) + .id('plvsa_chatroom_input_entry_layout') + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .margin({ + left: 8, + bottom: 8 + }) + + PLVSAGreetingView() + .id('plvsa_chatroom_greeting_layout') + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + bottom: { anchor: 'plvsa_chatroom_list_layout', align: VerticalAlign.Top } + }) + .margin({ + bottom: 16 + }) + + if (this.isShowChatInputLayout) { + PLVSAChatInputView({ + fullChatListData: this.fullChatListData, + chatListScroller: this.chatListScroller, + isShowChatInputLayout: this.isShowChatInputLayout, + reply: this.reply + }) + .id('plvsa_chatroom_input_layout') + .width('100%') + .alignRules({ + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + } + + PLVSARewardBar() + .id('plvsa_chatroom_reward_bar') + .alignRules({ + bottom: { anchor: 'plvsa_chatroom_greeting_layout', align: VerticalAlign.Top }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + .margin({ + bottom: 16 + }) + } + } + + onReplyData() { + PLVSAEventHub.on('plvsa_chat_reply', (reply: PLVChatQuoteDataBean) => { + this.reply = reply + this.isShowChatInputLayout = true + }) + } + + offReplyData() { + PLVSAEventHub.off('plvsa_chat_reply') + } + + aboutToDisappear(): void { + this.offReplyData() + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputEntryView.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputEntryView.ets new file mode 100644 index 0000000..52e7441 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputEntryView.ets @@ -0,0 +1,60 @@ +import { ChannelMenusBean, PLVCommonConstants } from '@polyvharmony/live-scenes-sdk' + +@Preview +@Component +export struct PLVSAChatInputEntryView { + @Link isQuizSelected: boolean + @Link isShowChatInputLayout: boolean + @Link quizMenu: ChannelMenusBean | undefined + @Link isCloseRoom: boolean + @Link isFocusModeOpen: boolean + + build() { + Row() { + Text() { + ImageSpan($r('app.media.plvsa_chat_msg')) + .width(14) + .height(14) + .margin({ right: 6, left: 8 }) + .verticalAlign(ImageSpanAlignment.CENTER) + Span(this.inputEntryText()) + .fontSize(14) + .fontColor('#99ffffff') + .width(PLVCommonConstants.FULL_PERCENT) + } + .layoutWeight(1) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + + if (this.quizMenu) { + Image(this.isQuizSelected ? $r('app.media.plvsa_chat_quiz_selected') : $r('app.media.plvsa_chat_quiz_default')) + .width(26) + .height(26) + .padding(4) + .margin({ right: 4 }) + .draggable(false) + .onClick(() => { + this.isQuizSelected = !this.isQuizSelected + }) + } + } + .onClick(() => { + if ((!this.isCloseRoom && !this.isFocusModeOpen) || this.isQuizSelected) { + this.isShowChatInputLayout = true + } + }) + .backgroundColor('#33000000') + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.End) + .borderRadius(100) + .height(32) + .constraintSize({ minWidth: 150, maxWidth: 180 }) + } + + inputEntryText() { + return this.isQuizSelected ? $r('app.string.plvsa_chat_input_tips_quiz') : + this.isCloseRoom ? $r('app.string.plvsa_chat_input_tips_chatroom_close') : + this.isFocusModeOpen ? $r('app.string.plvsa_chat_input_tips_focus') : + $r('app.string.plvsa_chat_input_tips_chat') + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputView.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputView.ets new file mode 100644 index 0000000..4cb267f --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatInputView.ets @@ -0,0 +1,349 @@ +import { + PLVBaseIdEvent, + PLVChatImgEvent, + PLVChatQuoteDataBean, + PLVChatroomError, + PLVChatroomErrorCode, + PLVCommonConstants, + PLVEmotionEvent, + PLVEmotionImageBean, + PLVLazyDataSource, + PLVLiveSceneSDK, + PLVLocalSpeakEvent, + PLVLogger, + PLVToastUtils +} from '@polyvharmony/live-scenes-sdk' +import { lateInit, runCatching, Disposable } from '@polyvharmony/media-player-sdk' +import { PhotoPickerComponent, PickerController, SelectMode } from '@ohos.file.PhotoPickerComponent' +import { ClickType, ItemInfo, ItemType, photoAccessHelper } from '@kit.MediaLibraryKit' +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus' + +const TAG = '[PLVSAChatInputView]' + +@Preview +@Component +export struct PLVSAChatInputView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + chatListScroller: ListScroller = new ListScroller() + @Link fullChatListData: PLVLazyDataSource + @Link isShowChatInputLayout: boolean + @Link reply: PLVChatQuoteDataBean | undefined + @LocalStorageLink('chatInputText') chatInputText: string = '' + @State private emotionSelectPanelVisible: boolean = false + @State private localImagePickerVisible: boolean = false + private readonly localImagePickerDialog = new CustomDialogController({ + builder: PLVSAChatLocalImageSelectDialog({ + localImagePickerVisible: this.localImagePickerVisible, + onSelectImage: (image: string) => { + this.sendLocalImage(image) + this.localImagePickerDialog.close() + } + }), + alignment: DialogAlignment.Bottom, + customStyle: true + }) + private onBackPressDisposable: Disposable | null = null + + aboutToAppear(): void { + this.onBackPressDisposable = this.pageDataBus.onBackPressHandler.register(20, () => this.onBackPress()) + } + + build() { + Column() { + Blank() + .onTouch(() => this.isShowChatInputLayout = false) + if (this.reply) { + Row() { + Text(this.replyText()) + .fontSize(12) + .fontColor('#F0F1F5') + .wordBreak(WordBreak.BREAK_ALL) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + .constraintSize({ maxWidth: '85%' }) + .padding({ left: 16, right: 10 }) + Blank() + Image($r('app.media.plvsa_chat_quote_message_close_icon')) + .width(32) + .height(32) + .padding(6) + .margin({ right: 4 }) + .draggable(false) + .onClick(() => { + this.reply = undefined + }) + } + .onTouch((event) => { + event.stopPropagation() + }) + .width(PLVCommonConstants.FULL_PERCENT) + .alignItems(VerticalAlign.Center) + .height(48) + .backgroundColor('#1B202D') + } + + Row() { + TextInput({ placeholder: this.inputPlaceText(), text: $$this.chatInputText }) + .height(32) + .layoutWeight(1) + .enterKeyType(EnterKeyType.Send) + .onSubmit((key, event) => { + event.keepEditableState() + this.speak() + }) + .onAppear(() => { + focusControl.requestFocus('chatTextInput') + }) + .fontSize(14) + .padding({ left: 16, right: 16 }) + .margin({ + right: 8 + }) + .placeholderColor('#4cffffff') + .fontColor('#F0F1F5') + .maxLength(200) + .maxLines(1) + .backgroundColor('#80464646') + .borderRadius(4) + .id('chatTextInput') + + Image($r("app.media.plvsa_chat_input_emotion_icon")) + .width(32) + .height(32) + .padding(2) + .onClick(() => { + this.emotionSelectPanelVisible = !this.emotionSelectPanelVisible + }) + Image($r("app.media.plvsa_chat_select_image_icon")) + .width(32) + .height(32) + .padding(2) + .onClick(() => { + this.localImagePickerDialog.open() + }) + } + .onTouch((event) => { + event.stopPropagation() + }) + .width(PLVCommonConstants.FULL_PERCENT) + .height(44) + .alignItems(VerticalAlign.Center) + .padding({ left: 8, right: 8 }) + .backgroundColor('#535353') + + if (this.emotionSelectPanelVisible) { + PLVSAChatEmotionLayout({ + onClickEmotionImage: (emotion: PLVEmotionImageBean) => { + this.sendEmotionImage(emotion) + } + }) + } + } + .width(PLVCommonConstants.FULL_PERCENT) + .height(PLVCommonConstants.FULL_PERCENT) + } + + private speak() { + if (this.chatInputText.trim().length == 0) { + PLVToastUtils.shortShow($r('app.string.plvsa_chat_toast_send_text_empty')) + return + } + const handleSendSuccess = (event: PLVLocalSpeakEvent) => { + this.fullChatListData.pushData(event) + this.chatListScroller.scrollEdge(Edge.Bottom) + this.isShowChatInputLayout = false + this.chatInputText = '' + this.reply = undefined + } + this.sdk?.chatroomManager.speak(this.chatInputText, this.reply) + .then((speakEvent) => { + handleSendSuccess(speakEvent) + }) + .catch((err: PLVChatroomError) => { + PLVLogger.printError(TAG, `speak fail`, err as Error) + if (PLVChatroomErrorCode.USER_IS_BANNED == err.code) { + // 被禁言也认为发言成功,并添加到聊天列表中,但不会广播给其他用户 + handleSendSuccess(err.data as PLVLocalSpeakEvent) + } else { + PLVToastUtils.shortShow(`speak fail: ${err.message}`) + } + }) + } + + private async sendEmotionImage(emotion: PLVEmotionImageBean): Promise { + const result = await runCatching(this.sdk?.chatroomManager.sendEmotionImage(emotion)) + const handleSendSuccess = (event: PLVEmotionEvent) => { + this.fullChatListData.pushData(event) + this.chatListScroller.scrollEdge(Edge.Bottom) + this.isShowChatInputLayout = false + } + if (result.success === true) { + handleSendSuccess(result.data) + } else { + if (result.error instanceof PLVChatroomError) { + const err = result.error + PLVLogger.printError(TAG, `sendEmotionImage fail`, err as Error) + if (PLVChatroomErrorCode.USER_IS_BANNED === err.code) { + handleSendSuccess(err.data as PLVEmotionEvent) + } else { + PLVToastUtils.shortShow(`speak fail: ${err.message}`) + } + } else { + PLVToastUtils.shortShow(`speak fail: ${result.error.message}`) + } + } + } + + private async sendLocalImage(image: string): Promise { + const result = await runCatching(this.sdk?.chatroomManager.sendLocalImage(image)) + const handleSendSuccess = (event: PLVChatImgEvent) => { + this.fullChatListData.pushData(event) + this.chatListScroller.scrollEdge(Edge.Bottom) + this.isShowChatInputLayout = false + } + if (result.success === true) { + handleSendSuccess(result.data) + } else { + if (result.error instanceof PLVChatroomError) { + const err = result.error + PLVLogger.printError(TAG, `sendEmotionImage fail`, err as Error) + if (PLVChatroomErrorCode.USER_IS_BANNED === err.code) { + handleSendSuccess(err.data as PLVChatImgEvent) + } else { + PLVToastUtils.shortShow(`speak fail: ${err.message}`) + } + } else { + PLVToastUtils.shortShow(`speak fail: ${result.error.message}`) + } + } + } + + replyText() { + let content = this.reply?.content + if (this.reply?.isChatImgEvent()) { + content = '[图片]' + } else if (this.reply?.isFileShareEvent()) { + content = this.reply?.fileData?.name + } + return `${this.reply?.nick}: ${content}` + } + + inputPlaceText() { + return $r('app.string.plvsa_chat_input_tips_chat') + } + + onBackPress(): boolean { + if (this.localImagePickerVisible) { + this.localImagePickerDialog.close() + return true + } + if (this.isShowChatInputLayout) { + this.isShowChatInputLayout = false + return true + } + return false + } + + aboutToDisappear(): void { + this.onBackPressDisposable?.dispose() + } + +} + +@Component +struct PLVSAChatEmotionLayout { + onClickEmotionImage: (emotion: PLVEmotionImageBean) => void = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private emotionImages: PLVEmotionImageBean[] = [] + + aboutToAppear(): void { + this.emotionImages = this.sdk.chatroomManager.emotions ?? [] + this.sdk.chatroomManager.eventNotify.on('emotions', this.onEmotionImagesUpdate) + } + + build() { + Tabs({ + barPosition: BarPosition.End + }) { + TabContent() { + Grid() { + ForEach( + this.emotionImages, + (emotionImage: PLVEmotionImageBean) => { + GridItem() { + Column() { + Image(emotionImage.url) + .padding(10) + .objectFit(ImageFit.Contain) + Text(emotionImage.title) + .fontSize(12) + .fontColor('#ADADC0') + } + .onClick(() => this.onClickEmotionImage(emotionImage)) + } + }, + (emotionImage: PLVEmotionImageBean) => emotionImage.id + ) + } + .columnsTemplate('1fr 1fr 1fr 1fr 1fr') + } + .tabBar({ + icon: $r('app.media.plvsa_chat_emotion_image_bar_icon') + }) + } + .width('100%') + .height(236) + .barHeight(40) + .barMode(BarMode.Scrollable) + .backgroundColor('#2B2C35') + .barBackgroundColor('#535353') + } + + private onEmotionImagesUpdate = (emotions: PLVEmotionImageBean[] | undefined) => { + this.emotionImages = emotions ?? [] + } + + aboutToDisappear(): void { + this.sdk.chatroomManager.eventNotify.off('emotions', this.onEmotionImagesUpdate) + } + +} + +@CustomDialog +struct PLVSAChatLocalImageSelectDialog { + onSelectImage: (image: string) => void = lateInit() + @Link localImagePickerVisible: boolean + controller: CustomDialogController = lateInit() + @State private readonly pickerController: PickerController = new PickerController(); + + aboutToAppear(): void { + this.localImagePickerVisible = true + } + + build() { + PhotoPickerComponent({ + pickerOptions: { + MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, + selectMode: SelectMode.SINGLE_SELECT + }, + onItemClicked: (itemInfo: ItemInfo, clickType: ClickType): boolean => { + if (itemInfo.itemType === ItemType.CAMERA) { + return true + } + return true + }, + onSelect: (uri: string) => { + this.onSelectImage(uri) + }, + pickerController: this.pickerController + }) + .width('100%') + .height('80%') + } + + aboutToDisappear(): void { + this.localImagePickerVisible = false + } + +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListItem.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListItem.ets new file mode 100644 index 0000000..ae04407 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListItem.ets @@ -0,0 +1,789 @@ +import { + IPLVCanOverLenEvent, + PLVBaseIdEvent, + PLVCallback, + PLVChannelData, + PLVChatImgEvent, + PLVChatPlaybackDataVO, + PLVChatQuoteDataBean, + PLVCommonConstants, + PLVEmotionEvent, + PLVHistoryChatImgEvent, + PLVHistoryFileShareEvent, + PLVHistoryRedPaperEvent, + PLVHistorySpeakEvent, + PLVImageBean, + PLVLiveSceneSDK, + PLVLocalQuizEvent, + PLVLocalQuizPromptEvent, + PLVLocalSpeakEvent, + PLVLogger, + PLVPPTShareFileDataBean, + PLVRedPaperEvent, + PLVRedPaperReceiveType, + PLVRewardEvent, + PLVSocketUserBean, + PLVSpeakEvent, + PLVTAnswerEvent, + PLVToastUtils, + PLVUserType, + PLVUtils, + PLVWebUtils, + RedPaperReceiveTypeEvent +} from '@polyvharmony/live-scenes-sdk' +import { PLVSAChatOverLengthMessageDialog } from './PLVSAChatOverLengthMessageDialog' +import { PLVSAEventHub } from './PLVSAEventHub' +import PLVSAFaceManager from './PLVSAFaceManager' + +const TAG = '[PLVSAChatListItem]' + +@Preview +@Component +export struct PLVSAChatListItem { + @ObjectLink itemData: PLVBaseIdEvent + + build() { + if (this.itemData instanceof PLVSpeakEvent) { // 在线发言/在线文件分享 + PLVChatSpeakView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVChatImgEvent) { // 在线图片 + PLVChatImgView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVLocalSpeakEvent) { // 本地发言 + PLVChatLocalSpeakView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVLocalQuizEvent) { // 本地提问 + PLVChatLocalQuizView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVTAnswerEvent) { // 在线回答/历史提问和回答 + PLVChatTAnswerView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVLocalQuizPromptEvent) { // 本地提问提示语 + PLVChatLocalQuizPromptView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVHistorySpeakEvent) { // 历史发言 + PLVChatHistorySpeakView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVHistoryChatImgEvent) { // 历史图片/历史个性表情 + PLVChatHistoryChatImgView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVRewardEvent) { // 在线打赏/历史打赏 + PLVChatRewardView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVEmotionEvent) { // 在线个性表情 + PLVChatEmotionView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVHistoryFileShareEvent) { // 历史文件分享 + PLVChatHistoryFileShareView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVRedPaperEvent + || this.itemData instanceof PLVHistoryRedPaperEvent) { // 在线口令红包/历史口令红包 + PLVChatRedPaperView({ itemData: this.itemData }) + } else if (this.itemData instanceof PLVChatPlaybackDataVO) { // 聊天回放消息 + PLVChatPlaybackView({ itemData: this.itemData }) + } + } +} + +@Component +export struct PLVChatSpeakView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @ObjectLink itemData: PLVSpeakEvent + @State nick: string | Resource | undefined = undefined + @State actor: string | undefined = undefined + @State userType: string | undefined = undefined + @State fullMessage: string | undefined = undefined + moreDialogController?: CustomDialogController = new CustomDialogController({ + builder: PLVSAChatOverLengthMessageDialog({ + nick: this.nick, + actor: this.actor, + userType: this.userType, + fullMessage: this.fullMessage + }), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + aboutToAppear(): void { + this.nick = generateNickByUser(this.itemData.user) + this.actor = this.itemData.user?.getActor() + this.userType = this.itemData.user?.userType + } + + build() { + messageView( + this.itemData.isFileShareEvent() ? this.itemData.fileData?.name : this.itemData.values?.[0], + this.actor, + this.userType, + this.nick, + this.itemData.isFileShareEvent() ? toImageBeanForFileShare(this.itemData.fileData) : undefined, + this.itemData.quote, + this.sdk?.chatroomManager.quoteReplyEnabled ? this.itemData._replyQuoteBean.get() : undefined, + this.itemData.parsedData, + this.itemData.isFileShareEvent() ? this.itemData.fileData?.url : undefined, + this.itemData._isOverLengthFoldingMessage.get(), + overLengthCopyClick(this.itemData.values?.[0], this.itemData, this.sdk), + overLengthMoreClick(this.itemData.values?.[0], this.itemData, this.sdk, (fullMessage: string) => { + this.fullMessage = fullMessage + this.moreDialogController?.open() + }) + ) + } +} + +@Component +export struct PLVChatImgView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @ObjectLink itemData: PLVChatImgEvent + + build() { + messageView( + undefined, + this.itemData.user?.getActor(), + this.itemData.user?.userType, + generateNick(this.itemData.user, this.sdk?.channelData), + PLVImageBean.toImageBeanForChatImg(this.itemData.values?.[0]), + undefined, + this.sdk?.chatroomManager.quoteReplyEnabled ? this.itemData._replyQuoteBean.get() : undefined + ) + } +} + +@Component +export struct PLVChatLocalSpeakView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @ObjectLink itemData: PLVLocalSpeakEvent + @State nick: string | Resource | undefined = undefined + @State actor: string | undefined = undefined + @State userType: string | undefined = undefined + @State fullMessage: string | undefined = undefined + moreDialogController?: CustomDialogController = new CustomDialogController({ + builder: PLVSAChatOverLengthMessageDialog({ + nick: this.nick, + actor: this.actor, + userType: this.userType, + fullMessage: this.fullMessage + }), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + aboutToAppear(): void { + this.nick = generateNickByChannelData(this.channelData) + this.actor = this.channelData?.viewerActor + this.userType = this.channelData?.viewerType + } + + build() { + messageView( + this.itemData.speakMessage, + this.actor, + this.userType, + this.nick, + undefined, + this.itemData.quote, + this.sdk?.chatroomManager.quoteReplyEnabled ? this.itemData._replyQuoteBean.get() : undefined, + this.itemData.parsedData, + undefined, + this.itemData._isOverLengthFoldingMessage.get(), + overLengthCopyClick(this.itemData.speakMessage, undefined, this.sdk), + overLengthMoreClick(this.itemData.speakMessage, undefined, this.sdk, (fullMessage: string) => { + this.fullMessage = fullMessage + this.moreDialogController?.open() + }) + ) + } +} + +@Component +export struct PLVChatLocalQuizView { + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @ObjectLink itemData: PLVLocalQuizEvent + + build() { + messageView( + this.itemData.quizMessage, + this.channelData?.viewerActor, + this.channelData?.viewerType, + generateNickByChannelData(this.channelData), + undefined, + undefined, + undefined, + this.itemData.parsedData + ) + } +} + +@Component +export struct PLVChatTAnswerView { + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @ObjectLink itemData: PLVTAnswerEvent + + build() { + messageView( + this.itemData.isImgType() ? undefined : this.itemData.content, + this.itemData.user?.getActor(), + this.itemData.user?.userType, + generateNick(this.itemData.user, this.channelData), + this.itemData.isImgType() ? this.itemData.image : undefined, + undefined, + undefined, + this.itemData.parsedData + ) + } +} + +@Component +export struct PLVChatLocalQuizPromptView { + @ObjectLink itemData: PLVLocalQuizPromptEvent + + build() { + promptView(this.itemData.prompt) + } +} + +@Component +export struct PLVChatHistorySpeakView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @ObjectLink itemData: PLVHistorySpeakEvent + @State nick: string | Resource | undefined = undefined + @State actor: string | undefined = undefined + @State userType: string | undefined = undefined + @State fullMessage: string | undefined = undefined + moreDialogController?: CustomDialogController = new CustomDialogController({ + builder: PLVSAChatOverLengthMessageDialog({ + nick: this.nick, + actor: this.actor, + userType: this.userType, + fullMessage: this.fullMessage + }), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + aboutToAppear(): void { + this.nick = generateNick(this.itemData.user, this.channelData) + this.actor = this.itemData.user?.getActor() + this.userType = this.itemData.user?.userType + } + + build() { + messageView( + this.itemData.content, + this.actor, + this.userType, + this.nick, + undefined, + this.itemData.quote, + this.sdk?.chatroomManager.quoteReplyEnabled ? this.itemData._replyQuoteBean.get() : undefined, + this.itemData.parsedData, + undefined, + this.itemData._isOverLengthFoldingMessage.get(), + overLengthCopyClick(this.itemData.content, this.itemData, this.sdk), + overLengthMoreClick(this.itemData.content, this.itemData, this.sdk, (fullMessage: string) => { + this.fullMessage = fullMessage + this.moreDialogController?.open() + }) + ) + } +} + +@Component +export struct PLVChatHistoryChatImgView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @ObjectLink itemData: PLVHistoryChatImgEvent + + build() { + messageView( + undefined, + this.itemData.user?.getActor(), + this.itemData.user?.userType, + generateNick(this.itemData.user, this.channelData), + PLVImageBean.toImageBeanForChatImg(this.itemData.content), + undefined, + this.sdk?.chatroomManager.quoteReplyEnabled ? this.itemData._replyQuoteBean.get() : undefined + ) + } +} + +@Component +export struct PLVChatRewardView { + @ObjectLink itemData: PLVRewardEvent + + build() { + rewardView(this.itemData) + } +} + +@Component +export struct PLVChatEmotionView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @ObjectLink itemData: PLVEmotionEvent + + build() { + messageView( + undefined, + this.itemData.user?.getActor(), + this.itemData.user?.userType, + generateNick(this.itemData.user, this.channelData), + PLVImageBean.toImageBeanForEmotion(this.itemData, this.sdk?.chatroomManager.emotions), + undefined, + this.sdk?.chatroomManager.quoteReplyEnabled ? this.itemData._replyQuoteBean.get(this.sdk?.chatroomManager.emotions) : undefined + ) + } +} + +@Component +export struct PLVChatHistoryFileShareView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @ObjectLink itemData: PLVHistoryFileShareEvent + + build() { + messageView( + this.itemData.fileData?.name, + this.itemData.user?.getActor(), + this.itemData.user?.userType, + generateNickByUser(this.itemData.user), + toImageBeanForFileShare(this.itemData.fileData), + undefined, + this.sdk?.chatroomManager.quoteReplyEnabled ? this.itemData._replyQuoteBean.get() : undefined, + undefined, + this.itemData.fileData?.url + ) + } +} + +@Component +export struct PLVChatRedPaperView { + @ObjectLink itemData: PLVRedPaperEvent + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + + aboutToAppear(): void { + this.sdk?.redpackManager.geLocalCachedReceiveStatus(this.itemData.redpackId) + .then((value) => { + this.itemData.receiveType = PLVRedPaperReceiveType.getValue(value as RedPaperReceiveTypeEvent) + this.sdk?.redpackManager.cacheRedPaper(this.itemData) + }) + } + + build() { + redPaperView( + this.itemData, + () => { + this.sdk?.interactManager?.receiveRedPaper(this.itemData) + } + ) + } +} + +@Component +export struct PLVChatPlaybackView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @Link itemData: PLVChatPlaybackDataVO + + build() { + messageView( + this.itemData.isImgMsgType() ? undefined : this.itemData.content, + this.itemData.actor, + this.itemData.userType, + generateNick(this.itemData.user, this.channelData), + this.itemData.isImgMsgType() ? PLVImageBean.toImageBeanForChatImg(this.itemData.chatImgContent) : undefined, + this.itemData.chatQuote, + undefined, + this.itemData.parsedData + ) + } +} + +/** + * 聊天消息View + * @param speakMsg 发言内容/提问内容/回答内容/文件分享的文件名 + * @param actor 用户头衔 + * @param userType 用户类型 + * @param nick 用户昵称 + * @param imgBean 图片/个性表情/文件分享的图片 + * @param quote 消息是否包含回复内容 + * @param reply 消息是否可以被回复的内容 + * @param parsedData 将speakMsg按表情文本解析后的数据 + * @param fileUrl 文件分享的url + * @param isOverLengthFoldingMessage 是否超长消息 + * @param overLengthCopyClick 超长消息复制点击回调 + * @param overLengthMoreClick 超长消息更多点击回调 + */ +@Builder +function messageView( + speakMsg?: string, + actor?: string, + userType?: string, + nick?: string | Resource, + imgBean?: PLVImageBean, + quote?: PLVChatQuoteDataBean, + reply?: PLVChatQuoteDataBean, + parsedData?: string[], + fileUrl?: string, + isOverLengthFoldingMessage?: boolean, + overLengthCopyClick?: PLVCallback, + overLengthMoreClick?: PLVCallback +) { + Column() { + ColumnSplit() { + if (quote) { + Column() { + Text() { + Span(quote.nick + ': ') + .fontColor('#FFFFFF') + .fontSize(12) + if (quote.isTextEvent()) { + if (quote.parsedData) { + ForEach(quote.parsedData, (data: string) => { + if (typeof PLVSAFaceManager.getFace(data) === 'string') { + Span(PLVSAFaceManager.getFace(data)) + .fontColor('#FFFFFF') + .fontSize(12) + } else { + ImageSpan(PLVSAFaceManager.getFace(data)) + .width(18) + .height(18) + .verticalAlign(ImageSpanAlignment.CENTER) + } + }) + } else { + Span(quote.content) + .fontColor('#FFFFFF') + .fontSize(12) + } + } else if (quote.isFileShareEvent()) { + Span(quote.fileData?.name) + .fontColor('#FFFFFF') + .fontSize(12) + } + } + .maxLines(2) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .constraintSize({ maxWidth: !quote.isTextEvent() ? 166 : Infinity }) + + if (quote.isChatImgEvent()) { + imageView(quote.image) + } else if (quote.isFileShareEvent()) { + imageView(toImageBeanForFileShare(quote.fileData), 8) + } + } + .alignItems(HorizontalAlign.Start) + .justifyContent(FlexAlign.Start) + } + + Column() { + Text() { + if (actor && PLVSocketUserBean.isSpecialType(userType)) { + Span(` ${actor} `) + .fontColor('#FFFFFF') + .textBackgroundStyle({ color: getActorBgByUserType(userType), radius: 7 }) + .fontSize(10) + } + Span(nick) + .fontColor('#FFD16B') + .fontSize(12) + if (parsedData) { + ForEach(parsedData, (data: string) => { + if (typeof PLVSAFaceManager.getFace(data) === 'string') { + Span(PLVSAFaceManager.getFace(data)) + .fontColor('#FFFFFF') + .fontSize(12) + } else { + ImageSpan(PLVSAFaceManager.getFace(data)) + .width(18) + .height(18) + .verticalAlign(ImageSpanAlignment.CENTER) + } + }) + } else if (speakMsg) { + Span(speakMsg) + .fontColor('#FFFFFF') + .fontSize(12) + } + } + .maxLines(speakMsg && isOverLengthFoldingMessage ? 5 : Infinity) + .constraintSize({ maxWidth: imgBean ? 166 : Infinity, minHeight: 24 }) + + imageView(imgBean, fileUrl ? 8 : 0) + } + .alignItems(HorizontalAlign.Start) + .justifyContent(FlexAlign.Start) + + if (speakMsg && isOverLengthFoldingMessage) { + Row() { + Text($r('app.string.plvsa_chat_copy')) + .height(PLVCommonConstants.FULL_PERCENT) + .textAlign(TextAlign.Center) + .fontColor('#CCFFFEFC') + .margin({ left: 8, right: 8 }) + .fontSize(14) + .layoutWeight(1) + .onClick(() => { + overLengthCopyClick?.() + }) + Divider() + .color('#4DD8D8D8') + .height(15) + .strokeWidth(1) + .vertical(true) + Text($r('app.string.plvsa_chat_more')) + .height(PLVCommonConstants.FULL_PERCENT) + .textAlign(TextAlign.Center) + .fontColor('#CCFFFEFC') + .margin({ left: 8, right: 8 }) + .fontSize(14) + .layoutWeight(1) + .onClick(() => { + overLengthMoreClick?.() + }) + } + .height(28) + .alignItems(VerticalAlign.Center) + .justifyContent(FlexAlign.Start) + } + } + .hitTestBehavior(HitTestMode.None) + .divider({ startMargin: 4, endMargin: 4 }) + } + .padding({ + left: 8, + right: 8, + top: 4, + bottom: 4 + }) + .alignItems(HorizontalAlign.Start) + .justifyContent(FlexAlign.Start) + .constraintSize({ minHeight: 20 }) + .backgroundColor('#33000000') + .borderRadius(14) + .bindContextMenu(((speakMsg && !isOverLengthFoldingMessage) || reply) ? menuView(speakMsg, reply, isOverLengthFoldingMessage) : undefined, ResponseType.LongPress, { + backgroundBlurStyle: BlurStyle.NONE, + backgroundColor: '#BF1B202D' + }) + .onClick(() => { + if (fileUrl) { + PLVWebUtils.openWebLink(fileUrl) + } + }) +} + +@Builder +function menuView(speakMsg?: string, reply?: PLVChatQuoteDataBean, isOverLengthFoldingMessage?: boolean) { + Column() { + ColumnSplit() { + if (speakMsg && !isOverLengthFoldingMessage) { + Button($r('app.string.plvsa_chat_copy')) + .backgroundColor(Color.Transparent) + .fontColor('#F0F1F5') + .fontSize(12) + .onClick(() => { + PLVUtils.copyText(speakMsg).then(() => { + PLVToastUtils.shortShow($r('app.string.plvsa_chat_copy_success')) + }) + }) + } + if (reply) { + Button($r('app.string.plvsa_chat_answer')) + .backgroundColor(Color.Transparent) + .fontColor('#F0F1F5') + .fontSize(12) + .onClick(() => { + PLVSAEventHub.emit(`plvsa_chat_reply`, reply) + }) + } + } + .divider({ startMargin: 2, endMargin: 2 }) + } + .alignItems(HorizontalAlign.Center) + .justifyContent(FlexAlign.Start) +} + +@Builder +function imageView(imgBean?: PLVImageBean, marginLeft?: number) { + if (imgBean) { + Image(imgBean.url) + .alt($r('app.media.plvsa_img_site')) + .width(adjustChatImgWH(imgBean.width, imgBean.height, 80, 60)[0]) + .height(adjustChatImgWH(imgBean.width, imgBean.height, 80, 60)[1]) + .margin({ left: marginLeft ? marginLeft : 0 }) + .objectFit(ImageFit.Auto) + .autoResize(true) + .borderRadius(6) + .draggable(false) + .onError((err) => { + PLVLogger.printError(TAG, `chat image url=${imgBean.url} load error`, new Error(err.message)) + }) + } +} + +@Builder +function promptView(prompt?: string | Resource) { + Text(prompt) + .fontColor('#FFD16B') + .fontSize(12) + .constraintSize({ minHeight: 20 }) + .padding({ + left: 8, + right: 8, + top: 4, + bottom: 4 + }) + .backgroundColor('#A8333333') + .borderRadius(6) +} + +@Builder +function rewardView(rewardEvent: PLVRewardEvent) { + Text() { + Span(rewardEvent.content?.unick + ' ') + .fontSize(12) + .fontColor('#ffffff') + Span($r('app.string.plvsa_reward_give', ' ')) + .fontSize(12) + .fontColor('#ffffff') + ImageSpan(rewardEvent.content?.getGimg()) + .width(20) + .height(20) + .verticalAlign(ImageSpanAlignment.CENTER) + if (rewardEvent.content?.goodNum && rewardEvent.content.goodNum > 1) { + Span(' x' + rewardEvent.content.goodNum) + .fontSize(12) + .fontColor('#ffffff') + } + } + .constraintSize({ minHeight: 20 }) + .padding({ + left: 8, + right: 8, + top: 4, + bottom: 4 + }) + .backgroundColor('#A8333333') + .borderRadius(6) +} + +@Builder +function redPaperView(redPaperEvent: PLVRedPaperEvent, getRedPaperClick?: PLVCallback) { + Text() { + ImageSpan($r('app.media.plvsa_chatroom_red_pack_icon')) + .width(20) + .height(20) + .verticalAlign(ImageSpanAlignment.CENTER) + Span($r('app.string.plvsa_red_paper_send_msg', redPaperEvent.user?.nick)) + .fontSize(12) + .fontColor('#FFFFFFFF') + Span(redPaperEvent.getTypeName()) + .fontSize(12) + .fontColor('#FFFFFFFF') + Span($r('app.string.plvsa_red_paper_dot')) + .fontSize(12) + .fontColor('#FFFFFFFF') + Span($r('app.string.plv_red_paper_get')) + .fontSize(12) + .fontColor('#FF5459') + .onClick((event) => { + getRedPaperClick?.() + }) + } + .constraintSize({ minHeight: 20 }) + .padding({ + left: 8, + right: 8, + top: 4, + bottom: 4 + }) + .backgroundColor('#A8333333') + .borderRadius(6) +} + +function generateNick(user?: PLVSocketUserBean, channelData?: PLVChannelData) { + return channelData?.viewerId == user?.userId ? generateNickByChannelData(channelData) : generateNickByUser(user) +} + +function generateNickByUser(user?: PLVSocketUserBean) { + return (user?.getActor() && PLVSocketUserBean.isSpecialType(user?.userType) ? ' ' : '') + `${user?.nick}: ` +} + +function generateNickByChannelData(channelData?: PLVChannelData) { + return $r('app.string.plvsa_chat_me', (channelData?.viewerActor && PLVSocketUserBean.isSpecialType(channelData?.viewerType) ? ' ' : '') + channelData?.viewerName, ': ') +} + +export function getActorBgByUserType(userType?: string) { + if (PLVUserType.USERTYPE_TEACHER == userType) { + return '#F09343' + } else if (PLVUserType.USERTYPE_ASSISTANT == userType) { + return '#598FE5' + } else if (PLVUserType.USERTYPE_GUEST == userType) { + return '#EB6165' + } else if (PLVUserType.USERTYPE_MANAGER == userType) { + return '#33BBC5' + } + return '' +} + +function adjustChatImgWH(widthVp: number, heightVp: number, maxVp: number, minVp: number) { + const percentage = widthVp / heightVp + if (percentage == 1) { // 方图 + if (widthVp < minVp) { + widthVp = heightVp = minVp + } else if (widthVp > maxVp) { + widthVp = heightVp = maxVp + } + } else if (percentage < 1) { // 竖图 + heightVp = maxVp + widthVp = Math.max(minVp, heightVp * percentage) + } else { // 横图 + widthVp = maxVp + heightVp = Math.max(minVp, widthVp / percentage) + } + return [widthVp, heightVp] +} + +function toImageBeanForFileShare(fileShareBean?: PLVPPTShareFileDataBean): PLVImageBean { + const imageBean = PLVImageBean.toImageBeanForFileShare(fileShareBean) + imageBean.width = 120 + imageBean.height = 144 + switch (fileShareBean?.suffix) { + case "ppt": + case "pptx": + imageBean.url = $r('app.media.plvsa_chatroom_file_share_ppt_icon') + break + case "doc": + case "docx": + imageBean.url = $r('app.media.plvsa_chatroom_file_share_doc_icon') + break + case "xls": + case "xlsx": + imageBean.url = $r('app.media.plvsa_chatroom_file_share_xls_icon') + break + case "pdf": + imageBean.url = $r('app.media.plvsa_chatroom_file_share_pdf_icon') + break + default: + break + } + return imageBean +} + +function overLengthCopyClick(message?: string, overLenEvent?: IPLVCanOverLenEvent, sdk?: PLVLiveSceneSDK) { + return () => { + if (overLenEvent?.overLen) { + overLenEvent._overLengthFullMessage.get((fullMessage) => { + PLVUtils.copyText(fullMessage).then(() => { + PLVToastUtils.shortShow($r('app.string.plvsa_chat_copy_success')) + }) + }, sdk?.chatroomManager) + } else { + PLVUtils.copyText(message || '').then(() => { + PLVToastUtils.shortShow($r('app.string.plvsa_chat_copy_success')) + }) + } + } +} + +function overLengthMoreClick(message?: string, overLenEvent?: IPLVCanOverLenEvent, sdk?: PLVLiveSceneSDK, fullMessageCallback?: PLVCallback) { + return () => { + if (overLenEvent?.overLen) { + overLenEvent._overLengthFullMessage.get((fullMessage) => { + fullMessageCallback?.(fullMessage) + }, sdk?.chatroomManager) + } else { + fullMessageCallback?.(message || '') + } + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListLayout.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListLayout.ets new file mode 100644 index 0000000..962ae85 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatListLayout.ets @@ -0,0 +1,471 @@ +import { + ChannelMenusBean, + PLVBaseIdEvent, + PLVBaseIdUserEvent, + PLVChannelData, + PLVChatImgEvent, + PLVCommonConstants, + PLVEmotionEvent, + PLVHistoryRedPaperEvent, + PLVJSONUtils, + PLVLazyDataSource, + PLVLiveSceneSDK, + PLVLocalQuizPromptEvent, + PLVRedPaperEvent, + PLVRedPaperForDelayEvent, + PLVRedPaperReceiveType, + PLVRedPaperResultEvent, + PLVRemoveContentEvent, + PLVRemoveHistoryEvent, + PLVRewardEvent, + PLVSimpleBuffer, + PLVSocketEvent, + PLVSocketOnEvent, + PLVSocketUserBean, + PLVSpeakEvent, + PLVTAnswerEvent, + PLVToastUtils, + RedPaperReceiveTypeEvent +} from '@polyvharmony/live-scenes-sdk' +import { PLVSAChatListItem } from './PLVSAChatListItem' + +const TAG = '[PLVSAChatListLayout]' + +@Preview +@Component +export struct PLVSAChatListLayout { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @LocalStorageLink('channelData') channelData?: PLVChannelData = undefined + @Link isQuizSelected: boolean + @Link @Watch('onFocusModeChanged') isFocusModeOpen: boolean + // 聊天 + chatListScroller: ListScroller = new ListScroller() + // 当前显示的数据列表 + @State chatListData: PLVLazyDataSource = new PLVLazyDataSource() + // 全部消息的数据列表 + @Link fullChatListData: PLVLazyDataSource + // 专注模式的数据列表(仅包括讲师类型、嘉宾类型、助教类型、管理员类型的信息) + @State focusModeChatListData: PLVLazyDataSource = new PLVLazyDataSource() + @State isChatListRefreshing: boolean = true + @State isChatListCanRefreshing: boolean = true + @State isShowChatNewMessageTips: boolean = false + getChatHistorySize: number = 10 + oldestChatHistoryTimestamp?: number + oldestChatHistoryTimestampCount?: number + socketMessageBuffer: PLVSimpleBuffer> = new PLVSimpleBuffer() + // 提问 + quizListScroller: ListScroller = new ListScroller() + @Link quizListData: PLVLazyDataSource + @Link quizMenu: ChannelMenusBean | undefined + @State isQuizListRefreshing: boolean = true + @State isQuizListCanRefreshing: boolean = true + @State isShowQuizNewMessageTips: boolean = false + getQuizHistoryPage: number = 1 + getQuizHistorySize: number = 10 + + aboutToAppear(): void { + this.initData() + this.onChatData() + } + + aboutToDisappear(): void { + this.socketMessageBuffer.release() + } + + build() { + Swiper() { + Stack({ alignContent: Alignment.BottomStart }) { + Refresh({ refreshing: $$this.isChatListRefreshing }) { + List({ space: 4, scroller: this.chatListScroller }) { + LazyForEach(this.chatListData, (item: PLVBaseIdEvent) => { + ListItem() { + PLVSAChatListItem({ itemData: item }) + } + }, (item: PLVBaseIdEvent) => item.getUniqueId()) + } + .onScrollIndex((start, end) => { + if (end == this.chatListData.totalCount() - 1) { + this.isShowChatNewMessageTips = false + } + }) + .scrollBar(BarState.Off) + .edgeEffect(EdgeEffect.Fade) + .cachedCount(5) + .width(PLVCommonConstants.FULL_PERCENT) + .height(PLVCommonConstants.FULL_PERCENT) + } + .onRefreshing(() => { + if (!this.isChatListCanRefreshing) { + this.isChatListRefreshing = false + return + } + this.getChatHistoryList() + }) + + if (this.isShowChatNewMessageTips) { + this.newMessageTips(() => { + this.isShowChatNewMessageTips = false + this.chatListScroller.scrollEdge(Edge.Bottom) + }) + } + } + .width(PLVCommonConstants.FULL_PERCENT) + .height(PLVCommonConstants.FULL_PERCENT) + + if (this.quizMenu) { + Stack({ alignContent: Alignment.BottomStart }) { + Column() { + Text($r('app.string.plvsa_chat_quiz_channel')) + .height(28) + .fontSize(14) + .fontColor('#ffffff') + .padding({ left: 10, right: 10 }) + .backgroundColor('#a6333333') + .borderRadius(14) + .margin({ bottom: 6 }) + + Refresh({ refreshing: $$this.isQuizListRefreshing }) { + List({ space: 4, scroller: this.quizListScroller }) { + LazyForEach(this.quizListData, (item: PLVBaseIdEvent) => { + ListItem() { + PLVSAChatListItem({ itemData: item }) + } + }, (item: PLVBaseIdEvent) => item.getUniqueId()) + } + .onScrollIndex((start, end) => { + if (end == this.quizListData.totalCount() - 1) { + this.isShowQuizNewMessageTips = false + } + }) + .scrollBar(BarState.Off) + .edgeEffect(EdgeEffect.Fade) + .cachedCount(5) + .width(PLVCommonConstants.FULL_PERCENT) + .height(PLVCommonConstants.FULL_PERCENT) + } + .onRefreshing(() => { + if (!this.isQuizListCanRefreshing) { + this.isQuizListRefreshing = false + return + } + this.getQuizHistoryList() + }) + .height(0) + .layoutWeight(1) + } + .alignItems(HorizontalAlign.Start) + + if (this.isShowQuizNewMessageTips) { + this.newMessageTips(() => { + this.isShowQuizNewMessageTips = false + this.quizListScroller.scrollEdge(Edge.Bottom) + }) + } + } + .width(PLVCommonConstants.FULL_PERCENT) + .height(PLVCommonConstants.FULL_PERCENT) + } + } + .width('100%') + .height('100%') + .loop(false) + .autoPlay(false) + .disableSwipe(true) + .nestedScroll(SwiperNestedScrollMode.SELF_FIRST) + .index(this.isQuizSelected ? 1 : 0) + .onChange((index) => { + this.isQuizSelected = index == 1 + }) + .indicator( + this.quizMenu ? Indicator.dot() + .left(0) + .bottom(0) + .itemWidth(38) + .itemHeight(3) + .selectedItemWidth(38) + .selectedItemHeight(3) + .color('#80ffffff') + .selectedColor(Color.White) : false + ) + } + + @Builder + newMessageTips(onClick?: () => void) { + Text($r("app.string.plvsa_chat_view_new_msg")) + .backgroundColor('#F0F1F5') + .borderRadius(30) + .padding({ + left: 8, + right: 8, + top: 4, + bottom: 4 + }) + .fontColor('#4399FF') + .fontSize(14) + .onClick(onClick) + } + + initData() { + this.chatListData.bindSource(this.fullChatListData) + } + + onChatData() { + this.socketMessageBuffer.observe((dataArr) => { + let pushChatListDataArr: PLVBaseIdEvent[] = [] + dataArr.forEach((value) => { + const data = value.message! + const event = value.eventName! + + let pushChatListData: PLVBaseIdEvent | undefined = undefined + let pushQuizListData: PLVBaseIdEvent | undefined = undefined + switch (event) { + // 发言 + case PLVSpeakEvent.EVENT: { + const speakEvent = PLVJSONUtils.toFillData(PLVSpeakEvent, data) + if (speakEvent) { + // 过滤聊天室广播的自己的发言消息 + if (this.channelData?.viewerId != speakEvent.user?.userId) { + pushChatListData = speakEvent + } + } + break + } + // 图片 + case PLVChatImgEvent.EVENT: { + const chatImgEvent = PLVJSONUtils.toFillData(PLVChatImgEvent, data) + if (chatImgEvent) { + // 过滤聊天室广播的自己的图片消息 + if (this.channelData?.viewerId != chatImgEvent.user?.userId) { + pushChatListData = chatImgEvent + } + } + break + } + // 打赏 + case PLVRewardEvent.EVENT: { + const rewardEvent = PLVJSONUtils.toFillData(PLVRewardEvent, data) + if (rewardEvent) { + pushChatListData = rewardEvent + } + break + } + // 口令红包 + case PLVRedPaperEvent.EVENT: { + const redPaperEvent = PLVJSONUtils.toFillData(PLVRedPaperEvent, data) + if (redPaperEvent && redPaperEvent.isSupportType()) { + pushChatListData = redPaperEvent + } + break + } + case PLVRedPaperResultEvent.EVENT: { + const redPaperResult = PLVJSONUtils.json2Bean(PLVRedPaperResultEvent, data) + if (redPaperResult) { + this.sdk?.redpackManager.onRedPaperResultEvent(redPaperResult) + } + break + } + // 延迟红包 + case PLVRedPaperForDelayEvent.EVENT: { + const redPaperForDelayEvent = PLVJSONUtils.json2Bean(PLVRedPaperForDelayEvent, data) + if (redPaperForDelayEvent) { + this.sdk?.redpackManager.notifyPostValue(redPaperForDelayEvent) + } + break + } + // 回答 + case PLVTAnswerEvent.EVENT: { + const tAnswerEvent = PLVJSONUtils.toFillData(PLVTAnswerEvent, data) + if (tAnswerEvent) { + // 只取回答自己的消息 + if (this.channelData?.viewerId == tAnswerEvent.s_userId) { + pushQuizListData = tAnswerEvent + } + } + break + } + // 删除某条消息 + case PLVRemoveContentEvent.EVENT: { + const removeContentEvent = PLVJSONUtils.json2Bean(PLVRemoveContentEvent, data) + if (removeContentEvent?.id) { + this.deleteDataToChatList(removeContentEvent.id) + } + break + } + // 清空所有消息 + case PLVRemoveHistoryEvent.EVENT: { + this.clearDataToChatList() + break + } + default: + break; + } + if (pushChatListData) { + pushChatListDataArr.push(pushChatListData) + } + if (pushQuizListData) { + this.pushDataToQuizList(pushQuizListData) + } + }) + if (pushChatListDataArr.length > 0) { + this.pushDataToChatList(...pushChatListDataArr) + } + }) + this.sdk?.chatroomManager.onData(PLVSocketOnEvent.MESSAGE, (data: string, event: string) => { + // 缓冲500ms再更新一次数据,避免聊天信息刷得太频繁导致UI卡顿 + this.socketMessageBuffer.push({ message: data, eventName: event } as PLVSocketEvent) + }, this) + this.sdk?.chatroomManager.onData(PLVSocketOnEvent.EMOTION, (data: string) => { + // 个性表情 + const emotionEvent = PLVJSONUtils.toFillData(PLVEmotionEvent, data) + if (emotionEvent) { + this.pushDataToChatList(emotionEvent) + } + }, this) + } + + getQuizHistoryList() { + this.sdk?.chatroomManager.getQuizHistoryList(this.getQuizHistoryPage, this.getQuizHistorySize) + .then((value) => { + if (this.getQuizHistoryPage == 1 && value.list?.length == 0) { + // 没有提问历史记录时,添加一条提问提示语 + const quizPromptEvent = new PLVLocalQuizPromptEvent() + quizPromptEvent.prompt = this.quizMenu?.content || $r('app.string.plvsa_chat_quiz_default_tips') + this.addDataToQuizList(quizPromptEvent) + } + if (value.list) { + value.list.forEach((data, index) => { + this.addDataToQuizList(data) + }) + if (this.getQuizHistoryPage == 1) { + this.quizListScroller.scrollEdge(Edge.Bottom) + } + this.getQuizHistoryPage++ + this.isQuizListRefreshing = false + if (value.list.length < this.getQuizHistorySize) { + this.isQuizListCanRefreshing = false + } + } + }) + .catch((err: Error) => { + this.isQuizListRefreshing = false + PLVToastUtils.shortShow($r('app.string.plvsa_chat_toast_history_load_failed', `: ${err.message}`)) + }) + } + + getChatHistoryList() { + this.sdk?.chatroomManager.getChatHistoryList(this.getChatHistorySize, this.oldestChatHistoryTimestamp, this.oldestChatHistoryTimestampCount) + .then((values) => { + const oldChatHistoryTimestamp = this.oldestChatHistoryTimestamp + values.forEach((value, index) => { + this.sdk?.chatroomManager.parseChatHistoryData(value, (data) => { + const messageTimestamp = data['time'] as number + if (!this.oldestChatHistoryTimestamp || messageTimestamp < this.oldestChatHistoryTimestamp) { + this.oldestChatHistoryTimestamp = messageTimestamp + this.oldestChatHistoryTimestampCount = 1 + } else if (this.oldestChatHistoryTimestamp == messageTimestamp && this.oldestChatHistoryTimestampCount) { + this.oldestChatHistoryTimestampCount++ + } + const baseIdEvent = data['data'] as PLVBaseIdEvent + if (baseIdEvent) { + this.addDataToChatList(baseIdEvent) + } + if (baseIdEvent instanceof PLVHistoryRedPaperEvent) { + const historyRedPagerEvent = baseIdEvent as PLVHistoryRedPaperEvent + const type = this.sdk?.redpackManager.geLocalCachedReceiveStatus(historyRedPagerEvent.redpackId) + .then((value) => { + historyRedPagerEvent.receiveType = PLVRedPaperReceiveType.getValue(value as RedPaperReceiveTypeEvent) + }) + + this.sdk?.redpackManager.cacheRedPaper((baseIdEvent as PLVHistoryRedPaperEvent)) + } + }) + }) + if (!oldChatHistoryTimestamp) { + this.chatListScroller.scrollEdge(Edge.Bottom) + } + this.isChatListRefreshing = false + if (values.length < this.getChatHistorySize) { + this.isChatListCanRefreshing = false + } + }) + .catch((err: Error) => { + this.isChatListRefreshing = false + PLVToastUtils.shortShow($r('app.string.plvsa_chat_toast_history_load_failed', `: ${err.message}`)) + }) + } + + clearDataToChatList() { + this.fullChatListData.clearData() + this.focusModeChatListData.clearData() + } + + deleteDataToChatList(id: string) { + this.fullChatListData.dataArray.some((value, index) => { + if (id === value.getUniqueId()) { + this.fullChatListData.deleteData(index) + return true + } + return false + }) + this.focusModeChatListData.dataArray.some((value, index) => { + if (id === value.getUniqueId()) { + this.focusModeChatListData.deleteData(index) + return true + } + return false + }) + } + + addDataToChatList(data: PLVBaseIdEvent) { + this.fullChatListData.addData(0, data) + if (data instanceof PLVBaseIdUserEvent) { + const isSpecialType = PLVSocketUserBean.isSpecialType((data as PLVBaseIdUserEvent).user?.userType) + if (isSpecialType) { + this.focusModeChatListData.addData(0, data) + } + } + } + + pushDataToChatList(...data: PLVBaseIdEvent[]) { + this.fullChatListData.pushData(...data) + const specialTypeData: PLVBaseIdEvent[] = [] + data.forEach((value) => { + if (value instanceof PLVBaseIdUserEvent) { + const isSpecialType = PLVSocketUserBean.isSpecialType((value as PLVBaseIdUserEvent).user?.userType) + if (isSpecialType) { + specialTypeData.push(value) + } + } + }) + this.focusModeChatListData.pushData(...specialTypeData) + if (this.chatListScroller.isAtEnd()) { + this.chatListScroller.scrollEdge(Edge.Bottom) + } else { + this.isShowChatNewMessageTips = true + } + } + + addDataToQuizList(data: PLVBaseIdEvent) { + this.quizListData.addData(0, data) + } + + pushDataToQuizList(data: PLVBaseIdEvent) { + this.quizListData.pushData(data) + if (this.quizListScroller.isAtEnd()) { + this.quizListScroller.scrollEdge(Edge.Bottom) + } else { + this.isShowQuizNewMessageTips = true + } + } + + onFocusModeChanged() { + this.chatListData.unbindSource() + if (this.isFocusModeOpen) { + this.chatListData.bindSource(this.focusModeChatListData) + this.focusModeChatListData.reloadData() + } else { + this.chatListData.bindSource(this.fullChatListData) + this.fullChatListData.reloadData() + } + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatOverLengthMessageDialog.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatOverLengthMessageDialog.ets new file mode 100644 index 0000000..5a2b617 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAChatOverLengthMessageDialog.ets @@ -0,0 +1,198 @@ +import { PLVCommonConstants, PLVDeviceUtils, PLVSocketUserBean, PLVTextUtils, PLVToastUtils, PLVUtils } from '@polyvharmony/live-scenes-sdk' +import { lateInit } from '@polyvharmony/media-player-sdk' +import { getActorBgByUserType } from './PLVSAChatListItem' +import PLVSAFaceManager from './PLVSAFaceManager' +import { display } from '@kit.ArkUI' + +@Preview +@CustomDialog +export struct PLVSAChatOverLengthMessageDialog { + controller?: CustomDialogController + scroller: Scroller = new Scroller() + @Link nick: string | Resource | undefined + @Link actor: string | undefined + @Link userType: string | undefined + @Link fullMessage: string + + build() { + if (this.isPortrait()) { + PLVSAChatOverLengthMessageDialogPort({ + nick: this.nick, + actor: this.actor, + userType: this.userType, + fullMessage: this.fullMessage + }) + } else { + PLVSAChatOverLengthMessageDialogLand({ + nick: this.nick, + actor: this.actor, + userType: this.userType, + fullMessage: this.fullMessage + }) + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } + +} + +@Component +struct PLVSAChatOverLengthMessageDialogPort { + scroller: Scroller = new Scroller() + nick: string | Resource | undefined + actor: string | undefined + userType: string | undefined + fullMessage: string = lateInit() + + build() { + Stack() { + Column() { + Text($r('app.string.plvsa_chat_full_text')) + .width(PLVCommonConstants.FULL_PERCENT) + .textAlign(TextAlign.Start) + .fontSize(18) + .fontColor('#F0F1F5') + Scroll(this.scroller) { + Text() { + if (this.actor && PLVSocketUserBean.isSpecialType(this.userType)) { + Span(` ${this.actor} `) + .fontColor('#ffffff') + .textBackgroundStyle({ color: getActorBgByUserType(this.userType), radius: 6 }) + .fontSize(12) + } + Span(this.nick) + .fontColor('#FFD16B') + .fontSize(14) + ForEach(PLVTextUtils.parseString(this.fullMessage), (data: string) => { + if (typeof PLVSAFaceManager.getFace(data) === 'string') { + Span(PLVSAFaceManager.getFace(data)) + .fontColor('#ffffff') + .fontSize(14) + } else { + ImageSpan(PLVSAFaceManager.getFace(data)) + .width(21) + .height(21) + .verticalAlign(ImageSpanAlignment.CENTER) + } + }) + } + } + .align(Alignment.TopStart) + .scrollBar(BarState.Off) + .margin({ top: 24, bottom: 24 }) + .height(0) + .layoutWeight(1) + + Button($r('app.string.plvsa_chat_copy')) + .width(88) + .height(28) + .fontSize(12) + .fontColor('#FFFFFF') + .onClick(() => { + PLVUtils.copyText(this.fullMessage).then(() => { + PLVToastUtils.shortShow($r('app.string.plvsa_chat_copy_success')) + }) + }) + } + .padding({ + left: 24, + right: 24, + top: 24, + bottom: PLVDeviceUtils.getNavigationIndicatorHeight() + 24 + }) + .width(PLVCommonConstants.FULL_PERCENT) + .height(PLVCommonConstants.FULL_PERCENT) + } + .borderRadius({ + topLeft: 12, + topRight: 12, + bottomLeft: 0, + bottomRight: 0 + }) + .width(PLVCommonConstants.FULL_PERCENT) + .height('65%') + .backgroundColor('#464646') + .backdropBlur(8) + } +} + +@Component +struct PLVSAChatOverLengthMessageDialogLand { + scroller: Scroller = new Scroller() + nick: string | Resource | undefined + actor: string | undefined + userType: string | undefined + fullMessage: string = lateInit() + + build() { + Stack() { + Column() { + Text($r('app.string.plvsa_chat_full_text')) + .width(PLVCommonConstants.FULL_PERCENT) + .textAlign(TextAlign.Start) + .fontSize(18) + .fontColor('#F0F1F5') + Scroll(this.scroller) { + Text() { + if (this.actor && PLVSocketUserBean.isSpecialType(this.userType)) { + Span(` ${this.actor} `) + .fontColor('#ffffff') + .textBackgroundStyle({ color: getActorBgByUserType(this.userType), radius: 6 }) + .fontSize(12) + } + Span(this.nick) + .fontColor('#FFD16B') + .fontSize(14) + ForEach(PLVTextUtils.parseString(this.fullMessage), (data: string) => { + if (typeof PLVSAFaceManager.getFace(data) === 'string') { + Span(PLVSAFaceManager.getFace(data)) + .fontColor('#ffffff') + .fontSize(14) + } else { + ImageSpan(PLVSAFaceManager.getFace(data)) + .width(21) + .height(21) + .verticalAlign(ImageSpanAlignment.CENTER) + } + }) + } + } + .align(Alignment.TopStart) + .scrollBar(BarState.Off) + .margin({ top: 24, bottom: 24 }) + .height(0) + .layoutWeight(1) + + Button($r('app.string.plvsa_chat_copy')) + .width(88) + .height(28) + .fontSize(12) + .fontColor('#FFFFFF') + .onClick(() => { + PLVUtils.copyText(this.fullMessage).then(() => { + PLVToastUtils.shortShow($r('app.string.plvsa_chat_copy_success')) + }) + }) + } + .padding({ + left: 24, + right: 24, + top: 24, + bottom: PLVDeviceUtils.getNavigationIndicatorHeight() + 24 + }) + .width(PLVCommonConstants.FULL_PERCENT) + .height(PLVCommonConstants.FULL_PERCENT) + } + .borderRadius({ + topLeft: 12, + bottomLeft: 12 + }) + .width(330) + .height(PLVCommonConstants.FULL_PERCENT) + .backgroundColor('#464646') + .backdropBlur(8) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAEventHub.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAEventHub.ets new file mode 100644 index 0000000..f4af568 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAEventHub.ets @@ -0,0 +1,15 @@ +export type EventType = 'plvsa_chat_reply' + +export class PLVSAEventHub { + static on(event: EventType, callback: Function) { + getContext().eventHub.on(event, callback) + } + + static off(event: EventType, callback?: Function) { + getContext().eventHub.off(event, callback) + } + + static emit(event: EventType, ...args: Object[]) { + getContext().eventHub.emit(event, ...args) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAFaceManager.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAFaceManager.ets new file mode 100644 index 0000000..e9e4b04 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAFaceManager.ets @@ -0,0 +1,59 @@ +import { HashMap } from '@kit.ArkTS'; + +class PLVSAFaceManager { + private faceMap: HashMap = new HashMap() + + constructor() { + this.initFaceMap() + } + + private initFaceMap() { + this.faceMap.set('[呲牙]', $r('app.media.plvsa_face_101')); + this.faceMap.set('[大笑]', $r('app.media.plvsa_face_102')); + this.faceMap.set('[可爱]', $r('app.media.plvsa_face_103')); + this.faceMap.set('[害羞]', $r('app.media.plvsa_face_104')); + this.faceMap.set('[偷笑]', $r('app.media.plvsa_face_105')); + this.faceMap.set('[再见]', $r('app.media.plvsa_face_106')); + this.faceMap.set('[惊讶]', $r('app.media.plvsa_face_107')); + this.faceMap.set('[哭笑]', $r('app.media.plvsa_face_108')); + this.faceMap.set('[酷]', $r('app.media.plvsa_face_109')); + this.faceMap.set('[奸笑]', $r('app.media.plvsa_face_110')); + this.faceMap.set('[鼓掌]', $r('app.media.plvsa_face_111')); + this.faceMap.set('[大哭]', $r('app.media.plvsa_face_112')); + this.faceMap.set('[敲打]', $r('app.media.plvsa_face_113')); + this.faceMap.set('[吃瓜]', $r('app.media.plvsa_face_114')); + this.faceMap.set('[让我看看]', $r('app.media.plvsa_face_115')); + this.faceMap.set('[按脸哭]', $r('app.media.plvsa_face_116')); + this.faceMap.set('[打哈欠]', $r('app.media.plvsa_face_117')); + this.faceMap.set('[愤怒]', $r('app.media.plvsa_face_118')); + this.faceMap.set('[难过]', $r('app.media.plvsa_face_119')); + this.faceMap.set('[ok]', $r('app.media.plvsa_face_120')); + this.faceMap.set('[爱心]', $r('app.media.plvsa_face_121')); + this.faceMap.set('[加1]', $r('app.media.plvsa_face_122')); + this.faceMap.set('[心碎]', $r('app.media.plvsa_face_123')); + this.faceMap.set('[正确]', $r('app.media.plvsa_face_124')); + this.faceMap.set('[错误]', $r('app.media.plvsa_face_125')); + this.faceMap.set('[满分]', $r('app.media.plvsa_face_126')); + this.faceMap.set('[笔记]', $r('app.media.plvsa_face_127')); + this.faceMap.set('[胜利]', $r('app.media.plvsa_face_128')); + this.faceMap.set('[比心]', $r('app.media.plvsa_face_129')); + this.faceMap.set('[赞]', $r('app.media.plvsa_face_130')); + this.faceMap.set('[蛋糕]', $r('app.media.plvsa_face_131')); + this.faceMap.set('[礼物]', $r('app.media.plvsa_face_132')); + this.faceMap.set('[红包]', $r('app.media.plvsa_face_133')); + this.faceMap.set('[奶茶]', $r('app.media.plvsa_face_134')); + this.faceMap.set('[时钟]', $r('app.media.plvsa_face_135')); + this.faceMap.set('[晚安]', $r('app.media.plvsa_face_136')); + this.faceMap.set('[拍手]', $r('app.media.plvsa_face_137')); + this.faceMap.set('[鲜花]', $r('app.media.plvsa_face_138')); + } + + getFace(faceKey: string): Resource | string { + if (this.faceMap.hasKey(faceKey)) { + return this.faceMap.get(faceKey) + } + return faceKey + } +} + +export default new PLVSAFaceManager() \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAGreetingView.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAGreetingView.ets new file mode 100644 index 0000000..b1af38d --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSAGreetingView.ets @@ -0,0 +1,93 @@ +import { PLVCommonConstants, PLVJSONUtils, PLVLiveSceneSDK, PLVLoginEvent, PLVSocketOnEvent } from '@polyvharmony/live-scenes-sdk' + +const TAG = '[PLVSAGreetingView]' + +@Preview +@Component +export struct PLVSAGreetingView { + @LocalStorageLink('sdk') sdk?: PLVLiveSceneSDK = undefined + @State welcomeTips?: string | Resource = undefined + @State layoutWidthTranslateX: number = 0 + appearTimerId?: number + loginListSize: number = 0 + loginNickList: string[] = [] + + aboutToAppear(): void { + this.onChatData() + } + + build() { + if (this.welcomeTips) { + Text(this.welcomeTips) + .translate({ x: 268 * this.layoutWidthTranslateX - 268 }) + .width(268) + .height(22) + .onAppear(() => { + animateTo({ duration: 500, curve: Curve.Linear }, () => { + this.layoutWidthTranslateX = 1 + }) + this.appearTimerId = setTimeout(() => { + animateTo({ + duration: 250, curve: Curve.Linear, onFinish: () => { + this.welcomeTips = undefined + } + }, () => { + this.layoutWidthTranslateX = 0 + }) + }, 2500) + }) + .onDisAppear(() => { + this.layoutWidthTranslateX = 0 + clearTimeout(this.appearTimerId) + setTimeout(() => { + this.buildNextWelcomeTips() + }, PLVCommonConstants.DELAY_TIME_S) + }) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + .fontSize(14) + .padding({ left: 16, right: 3 }) + .fontColor('#ffffff') + .backgroundImage($r('app.media.plvsa_greet_bg')) + .backgroundImageSize(ImageSize.Cover) + } + } + + onChatData() { + this.sdk?.chatroomManager.onData(PLVSocketOnEvent.MESSAGE, (data: string, event: string) => { + switch (event) { + // 登录 + case PLVLoginEvent.EVENT: + const loginEvent = PLVJSONUtils.toFillData(PLVLoginEvent, data) + if (loginEvent) { + this.buildWelcomeTips(loginEvent) + } + break; + default: + break; + } + }, this) + } + + buildWelcomeTips(loginEvent: PLVLoginEvent) { + this.loginListSize++ + if (this.loginNickList.length < 100) { + this.loginNickList.push(loginEvent.user?.nick || '') + } + this.buildNextWelcomeTips() + } + + buildNextWelcomeTips() { + if (this.welcomeTips === undefined) { + if (this.loginListSize >= 10) { + this.loginNickList.length = 2 + this.welcomeTips = $r('app.string.plvsa_chat_welcome_join_multi', this.loginNickList.join('、'), this.loginListSize + '') + this.loginNickList.length = 0 + this.loginListSize = 0 + } else if (this.loginNickList.length >= 1) { + this.welcomeTips = $r('app.string.plvsa_chat_welcome_join', this.loginNickList.shift()) + this.loginListSize-- + } + } + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSARewardBar.ets b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSARewardBar.ets new file mode 100644 index 0000000..66a7860 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/chatroom/widget/PLVSARewardBar.ets @@ -0,0 +1,185 @@ +import { + PLVCommonConstants, + PLVJSONUtils, + PLVLiveSceneSDK, + PLVRewardEvent, + PLVSocketOnEvent +} from '@polyvharmony/live-scenes-sdk'; +import { isTextEmpty, lateInit, PLVMediaPlayerAppContext } from '@polyvharmony/media-player-sdk'; + +const REWARD_BAR_WIDTH = 270 + +@Component +export struct PLVSARewardBar { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private showRewardRunning: boolean = false + @State private translationX: number = -REWARD_BAR_WIDTH + @State private nickName: string = "" + @State private giftAction: Resource = $r('app.string.plvsa_reward_gift_give') + @State private giftName: string = "" + @State private giftImage: string | Resource = "" + @State private giftCount: number = 1 + private readonly rewardQueue: PLVRewardEvent[] = [] + + aboutToAppear(): void { + this.sdk?.chatroomManager.onData(PLVSocketOnEvent.MESSAGE, (data: string, event: string) => { + if (event === PLVRewardEvent.EVENT) { + this.onRewardEvent(data) + } + }, this) + } + + build() { + RelativeContainer() { + Image($r('app.media.plvsa_chat_reward_bg')) + .id('plvsa_chat_reward_bg') + .width('100%') + .height(40) + .objectFit(ImageFit.Fill) + .alignRules({ + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + + Column() { + Text(this.nickName) + .constraintSize({ + maxWidth: 124 + }) + .maxLines(1) + .textOverflow({ + overflow: TextOverflow.Ellipsis + }) + .ellipsisMode(EllipsisMode.END) + .fontColor('#FCF2A6') + .fontSize(14) + + Row() { + Text(this.giftAction) + .fontColor('#FFFFFF') + .fontSize(10) + Text(this.giftName) + .fontColor('#FFFFFF') + .fontSize(10) + .margin({ + left: 2 + }) + } + } + .id('plvsa_reward_bar_gift_content') + .alignItems(HorizontalAlign.Start) + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + center: { anchor: 'plvsa_chat_reward_bg', align: VerticalAlign.Center } + }) + .margin({ + left: 16 + }) + + Image(this.giftImage) + .id('plvsa_reward_bar_gift_image') + .width(56) + .objectFit(ImageFit.Cover) + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .margin({ + left: 150 + }) + + if (this.giftCount > 1) { + Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Baseline }) { + Text("x") + .fontColor('#F47E04') + .fontSize(20) + .fontStyle(FontStyle.Italic) + Text(this.giftCount.toString()) + .fontColor('#F47E04') + .fontSize(28) + .fontStyle(FontStyle.Italic) + .margin({ + left: 2 + }) + } + .id('plvsa_reward_bar_count_times') + .alignRules({ + left: { anchor: 'plvsa_reward_bar_gift_image', align: HorizontalAlign.End }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .margin({ + left: 4 + }) + } + } + .width(REWARD_BAR_WIDTH) + .translate({ + x: this.translationX + }) + } + + private onRewardEvent(data: string) { + const rewardEvent = PLVJSONUtils.toFillData(PLVRewardEvent, data); + if (rewardEvent === undefined) { + return + } + this.rewardQueue.push(rewardEvent) + if (this.rewardQueue.length > 10) { + this.rewardQueue.shift() + } + this.showFirstRewardEvent() + } + + private async showFirstRewardEvent() { + if (this.showRewardRunning) { + return + } + this.showRewardRunning = true + const rewardEvent = this.rewardQueue.shift() + if (rewardEvent === undefined) { + this.showRewardRunning = false + return + } + const isGift = !isTextEmpty(rewardEvent.content?.getGimg()) + this.nickName = rewardEvent.content?.unick ?? "" + if (isGift) { + this.giftAction = $r('app.string.plvsa_reward_gift_give') + this.giftName = rewardEvent.content?.rewardContent ?? "" + this.giftImage = rewardEvent.content?.getGimg() ?? "" + } else { + this.giftAction = $r('app.string.plvsa_reward_money_give') + this.giftName = `${rewardEvent.content?.rewardContent}${PLVMediaPlayerAppContext.getString($r('app.string.plvsa_reward_money_give_unit_cny'))}` + this.giftImage = $r('app.media.plvsa_chat_reward_money_img') + } + this.giftCount = rewardEvent.content?.goodNum ?? 1 + + this.getUIContext().animateTo( + { curve: Curve.Smooth, duration: 400 }, + () => { + this.translationX = 0 + } + ) + setTimeout(() => { + this.hideRewardOrShowNext() + }, 400 + 1200) + } + + private hideRewardOrShowNext() { + const hasNextReward = this.rewardQueue.length > 0 + if (hasNextReward) { + this.showRewardRunning = false + this.translationX = -REWARD_BAR_WIDTH + this.showFirstRewardEvent() + } else { + this.showRewardRunning = false + this.getUIContext().animateTo( + { curve: Curve.Smooth, duration: 400 }, + () => { + this.translationX = -REWARD_BAR_WIDTH + } + ) + } + } + + aboutToDisappear(): void { + } +} diff --git a/scenes_streamerAlone/src/main/ets/components/linkmic/PLVSALinkMicLayout.ets b/scenes_streamerAlone/src/main/ets/components/linkmic/PLVSALinkMicLayout.ets new file mode 100644 index 0000000..ed388cc --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/linkmic/PLVSALinkMicLayout.ets @@ -0,0 +1,904 @@ +import { + PLVCommonConstants, + PLVLinkMicPushResolutionRatio, + PLVLinkMicState, + PLVLinkMicVideoRenderParam, + PLVLinkMicViewer, + PLVLiveSceneSDK, + PLVStreamerState, + PLVUserType +} from '@polyvharmony/live-scenes-sdk' +import { + DerivedState, + derivedStateOf, + extendArray, + extendNumber, + isNullOrUndefined, + lateInit, + MutableObserver +} from '@polyvharmony/media-player-sdk' +import { PLVSAPageDataBus, PLVSAStreamerStage } from '../../common/PLVSAPageDataBus' +import { display } from '@kit.ArkUI' +import { common, wantAgent } from '@kit.AbilityKit' +import { backgroundTaskManager } from '@kit.BackgroundTasksKit' +import { + PLVSALinkMicMemberControlActionSwitcher, + PLVSALinkMicMemberControlDialog +} from './widgets/PLVSALinkMicMemberControlDialog' +import { PLVSALinkMicViewerTimerLayout } from './widgets/PLVSALinkMicViewerTimerLayout' + +@Component +export struct PLVSALinkMicLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State streamerStage: PLVSAStreamerStage = PLVSAStreamerStage.STARTUP + @State streamerState: PLVStreamerState = PLVStreamerState.NOT_START + @State layoutType: PLVSALinkMicLayoutType = PLVSALinkMicLayoutType.TILE + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.initCameraMicrophone() + this.sdk.streamerManager.streamerState.observe(it => this.streamerState = it) + .pushTo(this.observers) + this.pageDataBus.streamerStage.observe(it => this.streamerStage = it).pushTo(this.observers) + this.pageDataBus.linkmicLayoutType.observe(it => this.layoutType = it).pushTo(this.observers) + } + + private async initCameraMicrophone() { + await this.sdk.linkmicManager.initPromise + this.sdk.linkmicManager.enableCamera(true) + this.sdk.linkmicManager.enableMicrophone(true) + } + + build() { + Stack() { + if (this.streamerStage !== PLVSAStreamerStage.END) { + LinkMicKeepBackgroundTask() + } + + if (this.streamerStage === PLVSAStreamerStage.STARTUP) { + LinkMicPreviewLayout() + } else if (this.streamerStage === PLVSAStreamerStage.LIVE) { + if (this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER) { + LinkMicTeacherLayout() + } else { + LinkMicGuestLayout() + } + } + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +// + +@Component +struct LinkMicPreviewLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State localLinkMicViewer: PLVLinkMicViewer | undefined = undefined + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.localLinkMicViewer.observe(it => this.localLinkMicViewer = it) + .pushTo(this.observers) + } + + build() { + Stack() { + if (this.localLinkMicViewer !== undefined) { + PLVSALinkMicViewerItemView({ + viewer: this.localLinkMicViewer, + viewerInfoOverlayVisible: false + }) + .width('100%') + .height('100%') + } + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +// + +// + +@Component +struct LinkMicTeacherLayout { + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State layoutType: PLVSALinkMicLayoutType = PLVSALinkMicLayoutType.TILE + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.pageDataBus.linkmicLayoutType.observe(it => this.layoutType = it).pushTo(this.observers) + } + + build() { + if (this.layoutType === PLVSALinkMicLayoutType.TILE) { + LinkMicTileLayout() + } else if (this.layoutType === PLVSALinkMicLayoutType.SPEAKER) { + LinkMicSpeakerLayout() + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct LinkMicTileLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly screenWidth: number = px2vp(display.getDefaultDisplaySync().width) + private readonly screenHeight: number = px2vp(display.getDefaultDisplaySync().height) + @State linkmicViewers: PLVLinkMicViewer[] = [] + @State gridColumnsTemplate: string = '1fr 1fr' + @State viewerItemWidth: number | string = this.screenWidth + @State viewerItemHeight: number | string = this.screenHeight + @State gridWidth: number | string = '100%' + @State gridHeight: number | string = '100%' + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.channelLinkMicViewers.observe((viewers) => { + this.linkmicViewers = viewers + this.layoutViewers() + }) + .pushTo(this.observers) + } + + build() { + Stack() { + Grid() { + ForEach( + this.linkmicViewers, + (viewer: PLVLinkMicViewer) => { + GridItem() { + PLVSALinkMicViewerItemView({ + viewer: viewer + }) + } + .width(this.viewerItemWidth) + .height(this.viewerItemHeight) + }, + (viewer: PLVLinkMicViewer) => viewer.xcomponentId + ) + } + .width(this.gridWidth) + .height(this.gridHeight) + .columnsTemplate(this.gridColumnsTemplate) + } + .width('100%') + .height('100%') + .alignContent(Alignment.Center) + } + + private layoutViewers() { + const viewers = this.linkmicViewers + const isPortrait = this.pageDataBus.isPortrait.value; + if (viewers.length <= 1) { + this.gridColumnsTemplate = '1fr' + this.viewerItemWidth = '100%' + this.viewerItemHeight = '100%' + this.gridHeight = '100%' + } else if (viewers.length <= 2) { + this.gridColumnsTemplate = '1fr 1fr' + if (isPortrait) { + this.viewerItemWidth = this.screenWidth / 2 + this.viewerItemHeight = this.viewerItemWidth / 2 * 3 + this.gridHeight = this.viewerItemHeight + } else { + this.viewerItemWidth = this.screenWidth / 2 + this.viewerItemHeight = this.viewerItemWidth / 3 * 2 + this.gridHeight = this.viewerItemHeight + } + } else if (viewers.length <= 4) { + this.gridColumnsTemplate = '1fr 1fr' + if (isPortrait) { + this.viewerItemWidth = this.screenWidth / 2 + this.viewerItemHeight = this.viewerItemWidth / 2 * 3 + const rows = Math.ceil(viewers.length / 2) + this.gridHeight = rows * this.viewerItemHeight + if (this.gridHeight > this.screenHeight) { + this.gridHeight = '100%' + } + } else { + this.gridWidth = this.screenHeight * 1.5 + this.gridHeight = '100%' + this.viewerItemWidth = '100%' + this.viewerItemHeight = '50%' + } + } else { + if (isPortrait) { + this.gridColumnsTemplate = '1fr 1fr 1fr' + this.viewerItemWidth = this.screenWidth / 3 + this.viewerItemHeight = this.viewerItemWidth / 2 * 3 + const rows = Math.ceil(viewers.length / 3) + this.gridHeight = rows * this.viewerItemHeight + if (this.gridHeight > this.screenHeight) { + this.gridHeight = '100%' + } + } else { + this.gridColumnsTemplate = '1fr 1fr 1fr 1fr' + this.viewerItemWidth = this.screenWidth / 4 + this.viewerItemHeight = this.viewerItemWidth / 3 * 2 + const rows = Math.ceil(viewers.length / 4) + this.gridHeight = rows * this.viewerItemHeight + if (this.gridHeight > this.screenHeight) { + this.gridHeight = '100%' + } + } + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct LinkMicSpeakerLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly screenWidth: number = px2vp(display.getDefaultDisplaySync().width) + private readonly screenHeight: number = px2vp(display.getDefaultDisplaySync().height) + @State isPortrait: boolean = true + @State linkmicViewers: PLVLinkMicViewer[] = [] + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.channelLinkMicViewers.observe((viewers) => { + this.linkmicViewers = viewers + }) + .pushTo(this.observers) + this.isPortrait = this.pageDataBus.isPortrait.value ?? true + } + + build() { + Stack() { + if (this.linkmicViewers.length === 1) { + PLVSALinkMicViewerItemView({ + viewer: this.linkmicViewers[0] + }) + .width('100%') + .height('100%') + } + + if (this.linkmicViewers.length > 1) { + RelativeContainer() { + Stack() { + PLVSALinkMicViewerItemView({ + viewer: this.linkmicViewers[0] + }) + } + .id('plvsa_linkmic_speaker_layout_main_container') + .width(this.screenWidth / 3 * 2) + .height('100%') + + Scroll() { + Column() { + ForEach( + this.linkmicViewers.slice(1), + (viewer: PLVLinkMicViewer) => { + GridItem() { + PLVSALinkMicViewerItemView({ + viewer: viewer + }) + } + .width('100%') + .aspectRatio(this.isPortrait ? 2 / 3 : 3 / 2) + }, + (viewer: PLVLinkMicViewer) => viewer.xcomponentId + ) + } + } + .id('plvsa_linkmic_speaker_layout_viewer_container') + .height('100%') + .scrollable(ScrollDirection.Vertical) + .align(Alignment.TopStart) + .alignRules({ + left: { anchor: "plvsa_linkmic_speaker_layout_main_container", align: HorizontalAlign.End }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End } + }) + } + .width('100%') + .height('100%') + .padding({ + top: this.isPortrait ? 78 : 0 + }) + } + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +// + +// + +@Component +struct LinkMicGuestLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private streamState: PLVStreamerState = PLVStreamerState.NOT_START + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.streamerState.observe(it => this.streamState = it) + .pushTo(this.observers) + } + + build() { + if (this.streamState === PLVStreamerState.START) { + LinkMicGuestLiveTileLayout() + } else { + LinkMicGuestNoLiveLayout() + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct LinkMicGuestNoLiveLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private localLinkMicViewer: PLVLinkMicViewer | undefined = undefined + @State private isPortrait: boolean = true + private observers: MutableObserver[] = [] + + aboutToAppear() { + this.sdk.linkmicManager.localLinkMicViewer.observe(it => this.localLinkMicViewer = it) + .pushTo(this.observers) + this.isPortrait = this.pageDataBus.isPortrait.value ?? true + } + + build() { + Stack() { + Grid() { + GridItem() { + Column() { + Image($r('app.media.plvsa_linkmic_no_stream_placeholder')) + .width(92) + .height(61) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_linkmic_no_stream_place_holder_text')) + .fontSize(12) + .fontColor('#E4E4E4') + } + .width('100%') + .height('100%') + .alignItems(HorizontalAlign.Center) + .justifyContent(FlexAlign.Center) + .linearGradient({ + angle: 45, + colors: [ + ['#383F64', 0], + ['#2D324C', 1] + ] + }) + } + .aspectRatio(this.isPortrait ? 2 / 3 : 3 / 2) + + GridItem() { + if (this.localLinkMicViewer) { + PLVSALinkMicViewerItemView({ + viewer: this.localLinkMicViewer + }) + } + } + .aspectRatio(this.isPortrait ? 2 / 3 : 3 / 2) + } + .width('100%') + .height('100%') + .columnsTemplate('1fr 1fr') + .padding({ + top: this.isPortrait ? 78 : 0 + }) + } + .width('100%') + .height('100%') + .alignContent(Alignment.Center) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct LinkMicGuestLiveTileLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly screenWidth: number = px2vp(display.getDefaultDisplaySync().width) + private readonly screenHeight: number = px2vp(display.getDefaultDisplaySync().height) + @State linkmicViewers: PLVLinkMicViewer[] = [] + @State gridColumnsTemplate: string = '1fr 1fr' + @State viewerItemWidth: number | string = this.screenWidth + @State viewerItemHeight: number | string = this.screenHeight + @State gridWidth: number | string = '100%' + @State gridHeight: number | string = '100%' + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const showChannelLinkMicViewersState = new DerivedState(() => { + const channelLinkMicViewers = this.sdk.linkmicManager.channelLinkMicViewers.value ?? [] + const localLinkMicViewer = this.sdk.linkmicManager.localLinkMicViewer.value + const listContainMyself = channelLinkMicViewers?.find(it => it.linkmicId === localLinkMicViewer?.linkmicId) !== undefined + if (listContainMyself) { + return channelLinkMicViewers + } + return extendArray([...channelLinkMicViewers.slice(0, 1), localLinkMicViewer, ...channelLinkMicViewers.slice(1)]) + .filterNotNull_ext() + }) + showChannelLinkMicViewersState.observe((viewers) => { + this.linkmicViewers = viewers + this.layoutViewers() + }) + .pushTo(this.observers) + } + + build() { + Stack() { + Grid() { + ForEach( + this.linkmicViewers, + (viewer: PLVLinkMicViewer) => { + GridItem() { + PLVSALinkMicViewerItemView({ + viewer: viewer + }) + } + .width(this.viewerItemWidth) + .height(this.viewerItemHeight) + }, + (viewer: PLVLinkMicViewer) => viewer.xcomponentId + ) + } + .width(this.gridWidth) + .height(this.gridHeight) + .columnsTemplate(this.gridColumnsTemplate) + } + .width('100%') + .height('100%') + .alignContent(Alignment.Center) + } + + private layoutViewers() { + const viewers = this.linkmicViewers + const isPortrait = this.pageDataBus.isPortrait.value; + if (viewers.length <= 1) { + this.gridColumnsTemplate = '1fr' + this.viewerItemWidth = '100%' + this.viewerItemHeight = '100%' + this.gridHeight = '100%' + } else if (viewers.length <= 2) { + this.gridColumnsTemplate = '1fr 1fr' + if (isPortrait) { + this.viewerItemWidth = this.screenWidth / 2 + this.viewerItemHeight = this.viewerItemWidth / 2 * 3 + this.gridHeight = this.viewerItemHeight + } else { + this.viewerItemWidth = this.screenWidth / 2 + this.viewerItemHeight = this.viewerItemWidth / 3 * 2 + this.gridHeight = this.viewerItemHeight + } + } else if (viewers.length <= 4) { + this.gridColumnsTemplate = '1fr 1fr' + if (isPortrait) { + this.viewerItemWidth = this.screenWidth / 2 + this.viewerItemHeight = this.viewerItemWidth / 2 * 3 + const rows = Math.ceil(viewers.length / 2) + this.gridHeight = rows * this.viewerItemHeight + if (this.gridHeight > this.screenHeight) { + this.gridHeight = '100%' + } + } else { + this.gridWidth = this.screenHeight * 1.5 + this.gridHeight = '100%' + this.viewerItemWidth = '100%' + this.viewerItemHeight = '50%' + } + } else { + if (isPortrait) { + this.gridColumnsTemplate = '1fr 1fr 1fr' + this.viewerItemWidth = this.screenWidth / 3 + this.viewerItemHeight = this.viewerItemWidth / 2 * 3 + const rows = Math.ceil(viewers.length / 3) + this.gridHeight = rows * this.viewerItemHeight + if (this.gridHeight > this.screenHeight) { + this.gridHeight = '100%' + } + } else { + this.gridColumnsTemplate = '1fr 1fr 1fr 1fr' + this.viewerItemWidth = this.screenWidth / 4 + this.viewerItemHeight = this.viewerItemWidth / 3 * 2 + const rows = Math.ceil(viewers.length / 4) + this.gridHeight = rows * this.viewerItemHeight + if (this.gridHeight > this.screenHeight) { + this.gridHeight = '100%' + } + } + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +// + +// + +@Component +export struct PLVSALinkMicFullScreenLayout { + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private fullScreenViewer: PLVLinkMicViewer | null = null + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.pageDataBus.linkmicFullScreenViewer.observe(it => this.fullScreenViewer = it).pushTo(this.observers) + } + + build() { + if (this.fullScreenViewer !== null) { + RelativeContainer() { + Stack() { + PLVSALinkMicViewerItemView({ + viewer: this.fullScreenViewer, + customOnClickItemOnce: () => { + }, + customOnClickItemTwice: () => { + this.pageDataBus.linkmicFullScreenViewer.setValue(null) + } + }) + } + .id('plvsa_linkmic_fullscreen_item_container') + .width('100%') + .height('100%') + + Image($r('app.media.plvsa_linkmic_fullscreen_exit_icon')) + .id('plvsa_linkmic_fullscreen_exit_icon') + .width(32) + .height(32) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End } + }) + .margin({ + top: 20, + right: 12 + }) + .onClick(() => { + this.pageDataBus.linkmicFullScreenViewer.setValue(null) + }) + } + .width('100%') + .height('100%') + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +// + +// + +@Component +struct PLVSALinkMicViewerItemView { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + viewer: PLVLinkMicViewer = lateInit() + viewerInfoOverlayVisible: boolean = true + customOnClickItemOnce: () => void = () => { + this.onClickItemViewOnce() + } + customOnClickItemTwice: () => void = () => { + this.onClickItemViewTwice() + } + @State isVideoEnable: boolean = false + @State isAudioEnable: boolean = false + @State audioVolume: number = 0 + @State viewerName: string | Resource = "" + @State guestLinkmicStateJoined: boolean = true + @State speakerIconVisible: boolean = false + @State isShowInFullScreen: boolean = false + @State videoRatio: number | null = null + private videoXComponentId: string = "" + private memberControlDialogSwitcher: PLVSALinkMicMemberControlActionSwitcher | undefined = undefined + private linkmicMemberControlDialogController: CustomDialogController | undefined = undefined + private tapCountTimeout: number | undefined = undefined + private tapCount = 0 + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.memberControlDialogSwitcher = new PLVSALinkMicMemberControlActionSwitcher(this.sdk, this.viewer) + this.viewer.isVideoEnable.observe((videoEnable) => this.isVideoEnable = videoEnable).pushTo(this.observers) + this.viewer.isAudioEnable.observe((audioEnable) => this.isAudioEnable = audioEnable).pushTo(this.observers) + this.viewer.audioVolume.observe((audioVolume) => this.audioVolume = audioVolume).pushTo(this.observers) + this.viewer.viewerName.observe((viewerName) => { + this.viewerName = this.viewer.isMyself ? $r('app.string.plvsa_chat_me', viewerName ?? "", "") : (viewerName ?? "") + }).pushTo(this.observers) + if (this.viewer.isMyself && this.sdk.channelData.viewerType !== PLVUserType.USERTYPE_TEACHER) { + this.sdk.linkmicManager.linkmicState.observe((linkmicState) => { + if (linkmicState === PLVLinkMicState.Joined) { + this.guestLinkmicStateJoined = true + } else { + this.guestLinkmicStateJoined = false + } + }) + .pushTo(this.observers) + } + this.sdk.linkmicManager.channelMainViewLinkMicId.observe(mainViewLinkMicId => { + const isSpeaker = !isNullOrUndefined(this.viewer.linkmicId) && this.viewer.linkmicId === mainViewLinkMicId + this.speakerIconVisible = this.viewer.viewerType !== PLVUserType.USERTYPE_TEACHER && isSpeaker + }) + .pushTo(this.observers) + this.pageDataBus.linkmicFullScreenViewer.observe(fullScreenViewer => { + this.isShowInFullScreen = this.viewer === fullScreenViewer + }).pushTo(this.observers) + const videoRatioState = derivedStateOf(() => { + const isLandscape = this.pageDataBus.isPortrait.value === false + const ratio = this.sdk.streamerManager.pushResolutionRatio.value ?? PLVLinkMicPushResolutionRatio.RATIO_16_9 + const linkmicOnlyTeacher = (this.sdk.linkmicManager.channelLinkMicViewers.value ?? []).length <= 1 + if (isLandscape && this.viewer.isMyself && linkmicOnlyTeacher && ratio !== PLVLinkMicPushResolutionRatio.RATIO_16_9) { + return ratio.ratio + } else { + return null + } + }) + videoRatioState.observe(it => this.videoRatio = it).pushTo(this.observers) + this.videoXComponentId = `${this.viewer.xcomponentId}-${Date.now()}` + } + + build() { + Stack() { + if (this.isVideoEnable && !this.isShowInFullScreen) { + // 摄像头画面 + XComponent({ + id: this.videoXComponentId, + type: "surface", + libraryname: this.viewer.xcomponentLibraryName + }) + .width(this.videoRatio === null ? '100%' : null) + .height('100%') + .aspectRatio(this.videoRatio === null ? null : this.videoRatio) + .onLoad(() => { + const renderParam = new PLVLinkMicVideoRenderParam( + this.viewer.linkmicId, + this.videoXComponentId + ) + this.sdk.linkmicManager.setupVideoRender(renderParam) + }) + .onDestroy(() => { + const renderParam = new PLVLinkMicVideoRenderParam( + this.viewer.linkmicId, + this.videoXComponentId + ) + this.sdk.linkmicManager.removeVideoRender(renderParam) + }) + } else { + // 未开启摄像头占位图 + Stack() { + Image($r('app.media.plvsa_linkmic_video_disabled_placeholder')) + .width(48) + .height(48) + } + .width('100%') + .height('100%') + .linearGradient({ + angle: 45, + colors: [ + ['#383F64', 0], + ['#2D324C', 1] + ] + }) + } + + if (this.viewerInfoOverlayVisible) { + RelativeContainer() { + // 音量提示图标 + Image(this.audioVolumeIcon()) + .id('linkmic_item_audio_volume_indicator') + .width(16) + .height(16) + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .margin({ + left: 6, + bottom: 8 + }) + + // 连麦成员名称 + Text(this.viewerName) + .id('linkmic_item_viewer_name') + .fontColor('#FFFFFF') + .fontSize(14) + .alignRules({ + left: { anchor: 'linkmic_item_audio_volume_indicator', align: HorizontalAlign.End }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End }, + center: { anchor: 'linkmic_item_audio_volume_indicator', align: VerticalAlign.Center } + }) + .margin({ + left: 3, + right: 10 + }) + .maxLines(1) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .ellipsisMode(EllipsisMode.END) + + Row({ space: 6 }) { + // 观众参与连麦计时 + if (!this.viewer.isMyself && this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER) { + PLVSALinkMicViewerTimerLayout({ + viewer: this.viewer + }) + } + // 嘉宾 连麦状态 + if (this.viewer.isMyself && this.viewer.viewerType === PLVUserType.USERTYPE_GUEST) { + Text(this.guestLinkmicStateJoined ? $r('app.string.plvsa_linkmic_guest_state_joined') : $r('app.string.plvsa_linkmic_guest_state_not_joined')) + .id('linkmic_item_guest_state_text') + .fontColor('#F0F1F5') + .fontSize(11) + .padding({ + top: 2, + bottom: 2, + left: 4, + right: 4 + }) + .borderRadius(8) + .backgroundColor(this.guestLinkmicStateJoined ? '#CC09C5B3' : '#CCF1453D') + } + // 主讲图标 + if (this.speakerIconVisible) { + Image($r('app.media.plvsa_linkmic_item_speaker_icon')) + .width(16) + .height(16) + } + } + .id('linkmic_item_top_left_corner_row') + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top } + }) + .margin({ + top: 2, + left: 2 + }) + + } + } + } + .width('100%') + .height('100%') + .onClick(() => this.onClickItemView()) + } + + private audioVolumeIcon(): Resource { + if (!this.isAudioEnable) { + return $r('app.media.plvsa_linkmic_audio_volume_closed') + } else { + const clampValue = extendNumber(this.audioVolume).coerceIn_ext(0, 100) + const normalizeVolume = Math.round(clampValue / 10) * 10 + return $r(`app.media.plvsa_linkmic_audio_volume_value_${normalizeVolume}`) + } + } + + private onClickItemView() { + const networkDisconnected = this.pageDataBus.networkDisconnectedMaskVisible.value ?? false + if (networkDisconnected) { + return + } + this.tapCount++ + if (this.tapCountTimeout === undefined) { + setTimeout(() => { + if (this.tapCount === 1) { + this.customOnClickItemOnce() + } else if (this.tapCount >= 2) { + this.customOnClickItemOnce() + } + this.tapCount = 0 + this.tapCountTimeout = undefined + }, 200) + } + if (this.tapCount >= 2) { + clearTimeout(this.tapCountTimeout) + this.customOnClickItemTwice() + this.tapCount = 0 + this.tapCountTimeout = undefined + } + } + + private onClickItemViewOnce() { + if (this.memberControlDialogSwitcher?.canShowMemberControlDialog !== true) { + return + } + this.linkmicMemberControlDialogController = new CustomDialogController({ + builder: PLVSALinkMicMemberControlDialog({ + viewer: this.viewer + }), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + this.linkmicMemberControlDialogController.open() + } + + private onClickItemViewTwice() { + this.pageDataBus.linkmicFullScreenViewer.setValue(this.viewer) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +// + +// + +@Component +struct LinkMicKeepBackgroundTask { + private readonly context = getContext(this) as common.UIAbilityContext + + async aboutToAppear(): Promise { + const wantAgentInfo: wantAgent.WantAgentInfo = { + wants: [ + { + bundleName: this.context.abilityInfo.bundleName, + abilityName: this.context.abilityInfo.name + } + ], + actionType: wantAgent.OperationType.START_ABILITY, + requestCode: 0, + actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] + }; + const wantAgentObject = await wantAgent.getWantAgent(wantAgentInfo) + await backgroundTaskManager.startBackgroundRunning(this.context, backgroundTaskManager.BackgroundMode.AUDIO_RECORDING, wantAgentObject) + } + + build() { + } + + async aboutToDisappear(): Promise { + await backgroundTaskManager.stopBackgroundRunning(this.context) + } +} + +// + +export enum PLVSALinkMicLayoutType { + /** + * 平铺 + */ + TILE = 2, + /** + * 主讲 + */ + SPEAKER = 3 +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicButton.ets b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicButton.ets new file mode 100644 index 0000000..937cb96 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicButton.ets @@ -0,0 +1,215 @@ +import { + PLVLinkMicMode, + PLVLinkMicState, + PLVLiveSceneSDK, + PLVToastUtils, + PLVUserType +} from '@polyvharmony/live-scenes-sdk'; +import { lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { PLVSAConfirmDialog } from '../../../common/widget/PLVSAConfirmDialog'; + +@Component +export struct PLVSALinkMicButton { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private isTeacher: boolean = true + + aboutToAppear(): void { + this.isTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + } + + build() { + if (this.isTeacher) { + LinkMicButtonTeacher() + } else { + LinkMicButtonGuest() + } + } + + aboutToDisappear(): void { + } +} + +@Component +struct LinkMicButtonTeacher { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly closeLinkMicDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_close_confirm_title'), + content: $r('app.string.plvsa_linkmic_close_confirm_content'), + onClickConfirm: (controller) => { + this.sdk.linkmicManager.closeLinkMic() + controller?.close() + } + }), + customStyle: true + }) + @State private isVisible: boolean = true + @State private isOpenLinkMic: boolean = false + @State private linkmicModeSelectPopupVisible: boolean = false + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.isLinkMicStrategyV2.observe(isLinkMicStrategyV2 => { + this.isVisible = !isLinkMicStrategyV2 + }) + .pushTo(this.observers) + this.sdk.linkmicManager.channelAllowRequestHandsUpLinkMic.observe(it => this.isOpenLinkMic = it) + .pushTo(this.observers) + } + + build() { + if (this.isVisible) { + Image(this.isOpenLinkMic ? $r('app.media.plvsa_linkmic_button_to_close') : $r('app.media.plvsa_linkmic_button_to_open')) + .width(36) + .height(36) + .onClick(() => { + if (!this.isOpenLinkMic) { + this.linkmicModeSelectPopupVisible = true + } else { + this.closeLinkMicDialogController.open() + } + }) + .bindPopup(this.linkmicModeSelectPopupVisible, { + builder: this.linkmicModeSelectPopup, + placement: Placement.Top, + backgroundBlurStyle: BlurStyle.NONE, + popupColor: '#BF1B202D', + radius: 8, + onStateChange: (event) => { + this.linkmicModeSelectPopupVisible = event.isVisible + } + }) + } + } + + @Builder + linkmicModeSelectPopup() { + Column() { + Text($r('app.string.plvsa_linkmic_mode_video')) + .fontSize(14) + .fontColor('#F0F1F5') + .padding(8) + .onClick(() => { + this.openLinkMic(PLVLinkMicMode.VIDEO) + this.linkmicModeSelectPopupVisible = false + }) + + Shape() + .width('calc(100% - 24vp)') + .height(1) + .margin({ + left: 12, + right: 12, + top: 2, + bottom: 2 + }) + .backgroundColor('#4D1B202D') + + Text($r('app.string.plvsa_linkmic_mode_audio')) + .fontSize(14) + .fontColor('#F0F1F5') + .padding(8) + .onClick(() => { + this.openLinkMic(PLVLinkMicMode.AUDIO) + this.linkmicModeSelectPopupVisible = false + }) + } + .width(106) + .padding({ + top: 6, + bottom: 6 + }) + } + + private openLinkMic(linkmicMode: PLVLinkMicMode) { + const channelLinkMicSettingEnable = (this.sdk.channelData.streamerData?.InteractNumLimit ?? 0) > 0 + if (!channelLinkMicSettingEnable) { + PLVToastUtils.shortShow($r('app.string.plvsa_linkmic_setting_not_open')); + return + } + this.sdk.linkmicManager.setLinkMicMode(linkmicMode) + this.sdk.linkmicManager.openLinkMic() + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct LinkMicButtonGuest { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private isVisible: boolean = true + @State private linkmicState: PLVLinkMicState = PLVLinkMicState.NoLinkMic + private readonly cancelRequestController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_guest_cancel_request_text'), + hasContent: false, + onClickConfirm: (controller) => { + this.sdk.linkmicManager.leaveLinkMic() + controller?.close() + } + }), + customStyle: true + }) + private readonly leaveLinkMicController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_guest_leave_linkmic_text'), + hasContent: false, + onClickConfirm: (controller) => { + this.sdk.linkmicManager.leaveLinkMic() + controller?.close() + } + }), + customStyle: true + }) + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const isChannelGuestAutoLinkMic = this.sdk.channelData.streamerData?.colinMicType === "auto" + this.isVisible = !isChannelGuestAutoLinkMic + this.sdk.linkmicManager.linkmicState.observe(it => this.linkmicState = it) + .pushTo(this.observers) + } + + build() { + if (this.isVisible) { + Image(this.linkmicButtonIcon()) + .width(36) + .height(36) + .onClick(() => { + this.onClickLinkMicButton() + }) + } + } + + private linkmicButtonIcon(): Resource { + switch (this.linkmicState) { + case PLVLinkMicState.NoLinkMic: + case PLVLinkMicState.Inviting: + default: + return $r('app.media.plvsa_linkmic_button_to_open') + case PLVLinkMicState.Requesting: + case PLVLinkMicState.WaitingResponse: + return $r('app.media.plvsa_linkmic_waiting_response_anim') + case PLVLinkMicState.Joined: + return $r('app.media.plvsa_linkmic_button_to_close') + } + } + + private onClickLinkMicButton() { + if (this.linkmicState === PLVLinkMicState.NoLinkMic) { + this.sdk.linkmicManager.requestLinkMic() + } else if (this.linkmicState === PLVLinkMicState.Requesting) { + this.cancelRequestController.open() + } else if (this.linkmicState === PLVLinkMicState.Joined) { + this.leaveLinkMicController.open() + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicInvitationLayout.ets b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicInvitationLayout.ets new file mode 100644 index 0000000..17c00f9 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicInvitationLayout.ets @@ -0,0 +1,208 @@ +import { PLVLinkMicState, PLVLiveSceneSDK, PLVScheduledTask } from '@polyvharmony/live-scenes-sdk'; +import { + DerivedState, + extendNumber, + lateInit, + millis, + MutableObserver, + seconds +} from '@polyvharmony/media-player-sdk'; +import { media } from '@kit.MediaKit'; +import { audio } from '@kit.AudioKit'; + +@Component +export struct PLVSALinkMicInvitationLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly invitationDialog = new CustomDialogController({ + builder: PLVSALinkMicInvitationDialog(), + autoCancel: false, + customStyle: true + }) + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const stateVisible = new DerivedState(() => { + const linkmicState = this.sdk.linkmicManager.linkmicState.value + const sdkSupportLinkMic = this.sdk.linkmicManager.sdkSupportChannelLinkMic.value ?? false + return linkmicState === PLVLinkMicState.Inviting && sdkSupportLinkMic + }) + stateVisible.observe((isVisible) => { + if (isVisible) { + this.invitationDialog.open() + } else { + this.invitationDialog.close() + } + }).pushTo(this.observers) + } + + build() { + + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@CustomDialog +struct PLVSALinkMicInvitationDialog { + controller: CustomDialogController = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State acceptInvitationTimeLeft: number = 0 + private taskUpdateTimeLeft: PLVScheduledTask | undefined = undefined + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.startTimeLeftCountDown() + } + + build() { + Column() { + // 连麦邀请铃声 + PLVSALinkMicInvitationSound() + + Text($r('app.string.plvsa_linkmic_invitation_dialog_title')) + .fontColor('#FFFFFF') + .fontWeight(FontWeight.Bold) + .fontSize(18) + .textAlign(TextAlign.Center) + + Text($r('app.string.plvsa_linkmic_invitation_dialog_content', this.acceptInvitationTimeLeft.toString())) + .fontColor('#BFFFFFFF') + .fontSize(14) + .textAlign(TextAlign.Center) + .margin({ + top: 12 + }) + + Row() { + Text($r('app.string.plvsa_linkmic_invitation_dialog_refuse')) + .layoutWeight(1) + .fontColor('#0382FF') + .fontSize(14) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + .borderRadius(18) + .borderColor('#0080FF') + .borderWidth(1) + .padding({ + top: 11, + bottom: 11 + }) + .onClick(() => { + this.sdk.linkmicManager.refuseLinkMicInvitation() + this.controller.close() + }) + Blank() + .width(10) + Text($r('app.string.plvsa_linkmic_invitation_dialog_accept')) + .layoutWeight(1) + .fontColor('#FFFFFF') + .fontSize(14) + .fontWeight(FontWeight.Bold) + .textAlign(TextAlign.Center) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: [ + ['#0080FF', 0], + ['#3399FF', 0] + ] + }) + .padding({ + top: 11, + bottom: 11 + }) + .onClick(() => { + this.sdk.linkmicManager.acceptLinkMicInvitation() + this.controller.close() + }) + } + .width('100%') + .margin({ + top: 25 + }) + } + .width(260) + .backgroundColor('#2C2C2C') + .borderRadius(16) + .padding({ + left: 24, + right: 24, + top: 20, + bottom: 18 + }) + } + + private startTimeLeftCountDown() { + this.stopTimeLeftCountDown() + this.taskUpdateTimeLeft = new PLVScheduledTask( + () => { + const now = Date.now() + const expire = this.sdk.linkmicManager.invitationExpireTimestamp.value ?? now + const timeLeft = millis(expire - now).toSeconds(Math.floor) + this.acceptInvitationTimeLeft = extendNumber(timeLeft).coerceAtLeast_ext(0) + }, + 0, + seconds(1).toMillis() + ) + this.taskUpdateTimeLeft.start() + } + + private stopTimeLeftCountDown() { + this.taskUpdateTimeLeft?.cancel() + this.taskUpdateTimeLeft = undefined + } + + aboutToDisappear(): void { + this.stopTimeLeftCountDown() + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSALinkMicInvitationSound { + private readonly soundFileName = "plvsa_linkmic_invitation_bgm.mp3" + private readonly resourceManager = getContext().resourceManager + private soundPool: media.SoundPool | undefined = undefined + private soundId: number | undefined = undefined + private streamId: number | undefined = undefined + + async aboutToAppear(): Promise { + const rawFd = await this.resourceManager.getRawFd(this.soundFileName) + const audioRenderInfo: audio.AudioRendererInfo = { + usage: audio.StreamUsage.STREAM_USAGE_MUSIC, + rendererFlags: 0 + } + this.soundPool = await media.createSoundPool(1, audioRenderInfo) + this.soundPool.load(rawFd.fd, rawFd.offset, rawFd.length) + this.soundPool.on('loadComplete', async (soundId) => { + this.soundId = soundId + const playParam: media.PlayParameters = { + loop: -1, + leftVolume: 1, + rightVolume: 1 + } + this.streamId = await this.soundPool?.play(this.soundId, playParam) + }) + } + + build() { + } + + async aboutToDisappear(): Promise { + this.soundPool?.off('loadComplete') + if (this.streamId !== undefined) { + this.soundPool?.stop(this.streamId) + this.streamId = undefined + } + if (this.soundId !== undefined) { + this.soundPool?.unload(this.soundId) + this.soundId = undefined + } + await this.soundPool?.release() + await this.resourceManager.closeRawFd(this.soundFileName) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicMemberControlDialog.ets b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicMemberControlDialog.ets new file mode 100644 index 0000000..7e28599 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicMemberControlDialog.ets @@ -0,0 +1,574 @@ +import { + PLVLinkMicMode, + PLVLinkMicViewer, + PLVLiveSceneSDK, + PLVSocketUserBean, + PLVUserType +} from '@polyvharmony/live-scenes-sdk'; +import { isTextEmpty, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus'; +import { PLVSAConfirmDialog } from '../../../common/widget/PLVSAConfirmDialog'; +import { display } from '@kit.ArkUI'; + +@CustomDialog +export struct PLVSALinkMicMemberControlDialog { + controller?: CustomDialogController = lateInit() + viewer: PLVLinkMicViewer = lateInit() + + build() { + if (this.isPortrait()) { + PLVSALinkMicMemberControlDialogPort({ + controller: this.controller, + viewer: this.viewer + }) + } else { + PLVSALinkMicMemberControlDialogLand({ + controller: this.controller, + viewer: this.viewer + }) + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSALinkMicMemberControlDialogPort { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + controller?: CustomDialogController = lateInit() + viewer: PLVLinkMicViewer = lateInit() + private switcher: PLVSALinkMicMemberControlActionSwitcher | undefined = undefined + @State private viewerName: string = "" + @State private isCameraEnable: boolean = false + @State private isMicrophoneEnable: boolean = false + @State private isMainView: boolean = false + private controlActionDialog: CustomDialogController | undefined = undefined + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.switcher = new PLVSALinkMicMemberControlActionSwitcher(this.sdk, this.viewer) + this.viewer.viewerName.observe(it => this.viewerName = it ?? "").pushTo(this.observers) + this.viewer.isVideoEnable.observe(it => this.isCameraEnable = it).pushTo(this.observers) + this.viewer.isAudioEnable.observe(it => this.isMicrophoneEnable = it).pushTo(this.observers) + this.sdk.linkmicManager.channelMainViewLinkMicId.observe(it => this.isMainView = this.viewer.linkmicId === it) + .pushTo(this.observers) + } + + build() { + Column() { + Stack() { + Image(this.viewer.viewerAvatar) + .width(66) + .height(66) + .alt($r('app.media.plvsa_member_default_avatar_student')) + .borderColor('#FFFFFF') + .borderWidth(1) + .borderRadius(66) + + if (!isTextEmpty(this.viewer.viewerActor)) { + Text(this.viewer.viewerActor) + .height(18) + .constraintSize({ + maxWidth: 42 + }) + .maxLines(1) + .textOverflow({ + overflow: TextOverflow.Ellipsis + }) + .ellipsisMode(EllipsisMode.END) + .textAlign(TextAlign.Center) + .fontColor('#F0F1F5') + .fontSize(12) + .padding({ + left: 3, + right: 3 + }) + .borderRadius(15) + .linearGradient({ + angle: 90, + colors: this.viewerActorBackground() + }) + .translate({ + y: 4 + }) + } + } + .height(48) + .alignContent(Alignment.Bottom) + + Text(this.viewerName) + .fontColor('#F0F1F5') + .fontSize(14) + .margin({ + top: 14 + }) + .maxLines(1) + + Divider() + .height(1) + .color('#19ffffff') + .margin({ + left: 24, + right: 24, + top: 24 + }) + + List() { + if (this.switcher?.showCameraControl) { + ListItem() { + MemberControlAction({ + icon: this.isCameraEnable ? $r('app.media.plvsa_more_camera_enable') : $r('app.media.plvsa_more_camera_disable'), + name: $r('app.string.plvsa_more_camera') + }).onClick(() => this.onClickCamera()) + } + } + + if (this.switcher?.showMicrophoneControl) { + ListItem() { + MemberControlAction({ + icon: this.isMicrophoneEnable ? $r('app.media.plvsa_more_microphone_enable') : $r('app.media.plvsa_more_microphone_disable'), + name: $r('app.string.plvsa_more_microphone') + }).onClick(() => this.onClickMicrophone()) + } + } + + if (this.switcher?.showHangupButton) { + ListItem() { + MemberControlAction({ + icon: $r('app.media.plvsa_linkmic_member_control_hang_up_linkmic'), + name: $r('app.string.plvsa_linkmic_member_control_hang_up_linkmic') + }).onClick(() => this.onClickHangup()) + } + } + + if (this.switcher?.showSpeakerControl) { + ListItem() { + MemberControlAction({ + icon: $r('app.media.plvsa_linkmic_speaker_icon'), + name: this.isMainView ? $r('app.string.plvsa_member_more_withdraw_speaker_permission') : $r('app.string.plvsa_member_more_grant_speaker_permission') + }).onClick(() => this.onClickSpeaker()) + } + } + + ListItem() { + MemberControlAction({ + icon: $r('app.media.plvsa_linkmic_member_control_fullscreen_icon'), + name: $r('app.string.plvsa_linkmic_member_control_full_screen') + }).onClick(() => this.onClickFullScreen()) + } + } + .width('100%') + .listDirection(Axis.Vertical) + .alignListItem(ListItemAlign.Center) + .lanes(4) + .margin({ + top: 24 + }) + + } + .id('plvsa_linkmic_member_control_layout_content') + .width('100%') + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + .padding({ + bottom: 18 + }) + } + + private viewerActorBackground(): [ResourceColor, number][] { + const viewerType = this.viewer.viewerType + if (viewerType === undefined) { + return [] + } + const linear = (start: ResourceColor, end: ResourceColor): [ResourceColor, number][] => [[start, 0], [end, 1]] + switch (viewerType) { + case PLVUserType.USERTYPE_TEACHER: + return linear('#FFA336', '#FFB95A') + case PLVUserType.USERTYPE_ASSISTANT: + return linear('#397ffe', '#73a1fe') + case PLVUserType.USERTYPE_MANAGER: + return linear('#32B6BF', '#35C4CF') + case PLVUserType.USERTYPE_GUEST: + default: + return linear('#FF2851', '#FE3182') + } + } + + private onClickCamera() { + this.sdk.linkmicManager.setViewerEnableCamera(this.viewer.viewerId!, !this.isCameraEnable) + this.controller?.close() + } + + private onClickMicrophone() { + this.sdk.linkmicManager.setViewerEnableMicrophone(this.viewer.viewerId!, !this.isMicrophoneEnable) + this.controller?.close() + } + + private onClickHangup() { + this.controlActionDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_member_control_hang_up_linkmic_confirm_title'), + hasContent: false, + onClickConfirm: (controller) => { + this.sdk.linkmicManager.hangupViewerLinkMic(this.viewer.viewerId!) + controller?.close() + this.controller?.close() + } + }), + customStyle: true + }) + this.controlActionDialog.open() + } + + private onClickSpeaker() { + const mainViewLinkMicId = this.sdk.linkmicManager.channelMainViewLinkMicId.value + const channelHasOtherSpeaker = mainViewLinkMicId !== undefined && mainViewLinkMicId !== this.sdk.channelData.loginChannelId + if (this.isMainView) { + // 移除主讲 + this.controlActionDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_member_control_withdraw_speaker_confirm_title'), + content: $r('app.string.plvsa_linkmic_member_control_withdraw_speaker_confirm_content'), + onClickConfirm: (controller) => { + this.sdk.linkmicManager.revokeSpeaker(this.viewer.viewerId!) + controller?.close() + this.controller?.close() + } + }), + customStyle: true + }) + this.controlActionDialog.open() + } else if (channelHasOtherSpeaker) { + // 转移主讲 + this.controlActionDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_member_control_grant_speaker_confirm_title'), + content: $r('app.string.plvsa_linkmic_member_control_grant_speaker_confirm_content'), + onClickConfirm: (controller) => { + this.sdk.linkmicManager.grantSpeaker(this.viewer.viewerId!) + controller?.close() + this.controller?.close() + } + }), + customStyle: true + }) + this.controlActionDialog.open() + } else { + // 直接授予主讲 + this.sdk.linkmicManager.grantSpeaker(this.viewer.viewerId!) + this.controller?.close() + } + } + + private onClickFullScreen() { + this.pageDataBus.linkmicFullScreenViewer.setValue(this.viewer) + this.controller?.close() + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSALinkMicMemberControlDialogLand { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + controller?: CustomDialogController = lateInit() + viewer: PLVLinkMicViewer = lateInit() + private switcher: PLVSALinkMicMemberControlActionSwitcher | undefined = undefined + @State private viewerName: string = "" + @State private isCameraEnable: boolean = false + @State private isMicrophoneEnable: boolean = false + @State private isMainView: boolean = false + private controlActionDialog: CustomDialogController | undefined = undefined + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.switcher = new PLVSALinkMicMemberControlActionSwitcher(this.sdk, this.viewer) + this.viewer.viewerName.observe(it => this.viewerName = it ?? "").pushTo(this.observers) + this.viewer.isVideoEnable.observe(it => this.isCameraEnable = it).pushTo(this.observers) + this.viewer.isAudioEnable.observe(it => this.isMicrophoneEnable = it).pushTo(this.observers) + this.sdk.linkmicManager.channelMainViewLinkMicId.observe(it => this.isMainView = this.viewer.linkmicId === it) + .pushTo(this.observers) + } + + build() { + Column() { + Stack() { + Image(this.viewer.viewerAvatar) + .width(66) + .height(66) + .alt($r('app.media.plvsa_member_default_avatar_student')) + .borderColor('#FFFFFF') + .borderWidth(1) + .borderRadius(66) + + if (!isTextEmpty(this.viewer.viewerActor)) { + Text(this.viewer.viewerActor) + .height(18) + .constraintSize({ + maxWidth: 42 + }) + .maxLines(1) + .textOverflow({ + overflow: TextOverflow.Ellipsis + }) + .ellipsisMode(EllipsisMode.END) + .textAlign(TextAlign.Center) + .fontColor('#F0F1F5') + .fontSize(12) + .padding({ + left: 3, + right: 3 + }) + .borderRadius(15) + .linearGradient({ + angle: 90, + colors: this.viewerActorBackground() + }) + .translate({ + y: 4 + }) + } + } + .height(66) + .alignContent(Alignment.Bottom) + .margin({ + top: 32 + }) + + Text(this.viewerName) + .fontColor('#F0F1F5') + .fontSize(14) + .margin({ + top: 14 + }) + .maxLines(1) + + Divider() + .height(1) + .color('#19ffffff') + .margin({ + left: 24, + right: 24, + top: 24 + }) + + Grid() { + if (this.switcher?.showCameraControl) { + GridItem() { + MemberControlAction({ + icon: this.isCameraEnable ? $r('app.media.plvsa_more_camera_enable') : $r('app.media.plvsa_more_camera_disable'), + name: $r('app.string.plvsa_more_camera') + }).onClick(() => this.onClickCamera()) + } + } + + if (this.switcher?.showMicrophoneControl) { + GridItem() { + MemberControlAction({ + icon: this.isMicrophoneEnable ? $r('app.media.plvsa_more_microphone_enable') : $r('app.media.plvsa_more_microphone_disable'), + name: $r('app.string.plvsa_more_microphone') + }).onClick(() => this.onClickMicrophone()) + } + } + + if (this.switcher?.showHangupButton) { + GridItem() { + MemberControlAction({ + icon: $r('app.media.plvsa_linkmic_member_control_hang_up_linkmic'), + name: $r('app.string.plvsa_linkmic_member_control_hang_up_linkmic') + }).onClick(() => this.onClickHangup()) + } + } + + if (this.switcher?.showSpeakerControl) { + GridItem() { + MemberControlAction({ + icon: $r('app.media.plvsa_linkmic_speaker_icon'), + name: this.isMainView ? $r('app.string.plvsa_member_more_withdraw_speaker_permission') : $r('app.string.plvsa_member_more_grant_speaker_permission') + }).onClick(() => this.onClickSpeaker()) + } + } + + GridItem() { + MemberControlAction({ + icon: $r('app.media.plvsa_linkmic_member_control_fullscreen_icon'), + name: $r('app.string.plvsa_linkmic_member_control_full_screen') + }).onClick(() => this.onClickFullScreen()) + } + } + .width('100%') + .layoutWeight(1) + .columnsTemplate('1fr 1fr 1fr') + .margin({ + top: 24 + }) + + } + .id('plvsa_linkmic_member_control_layout_content') + .width(300) + .height('100%') + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + } + + private viewerActorBackground(): [ResourceColor, number][] { + const viewerType = this.viewer.viewerType + if (viewerType === undefined) { + return [] + } + const linear = (start: ResourceColor, end: ResourceColor): [ResourceColor, number][] => [[start, 0], [end, 1]] + switch (viewerType) { + case PLVUserType.USERTYPE_TEACHER: + return linear('#FFA336', '#FFB95A') + case PLVUserType.USERTYPE_ASSISTANT: + return linear('#397ffe', '#73a1fe') + case PLVUserType.USERTYPE_MANAGER: + return linear('#32B6BF', '#35C4CF') + case PLVUserType.USERTYPE_GUEST: + default: + return linear('#FF2851', '#FE3182') + } + } + + private onClickCamera() { + this.sdk.linkmicManager.setViewerEnableCamera(this.viewer.viewerId!, !this.isCameraEnable) + this.controller?.close() + } + + private onClickMicrophone() { + this.sdk.linkmicManager.setViewerEnableMicrophone(this.viewer.viewerId!, !this.isMicrophoneEnable) + this.controller?.close() + } + + private onClickHangup() { + this.controlActionDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_member_control_hang_up_linkmic_confirm_title'), + hasContent: false, + onClickConfirm: (controller) => { + this.sdk.linkmicManager.hangupViewerLinkMic(this.viewer.viewerId!) + controller?.close() + this.controller?.close() + } + }), + customStyle: true + }) + this.controlActionDialog.open() + } + + private onClickSpeaker() { + const mainViewLinkMicId = this.sdk.linkmicManager.channelMainViewLinkMicId.value + const channelHasOtherSpeaker = mainViewLinkMicId !== undefined && mainViewLinkMicId !== this.sdk.channelData.loginChannelId + if (this.isMainView) { + // 移除主讲 + this.controlActionDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_member_control_withdraw_speaker_confirm_title'), + content: $r('app.string.plvsa_linkmic_member_control_withdraw_speaker_confirm_content'), + onClickConfirm: (controller) => { + this.sdk.linkmicManager.revokeSpeaker(this.viewer.viewerId!) + controller?.close() + this.controller?.close() + } + }), + customStyle: true + }) + this.controlActionDialog.open() + } else if (channelHasOtherSpeaker) { + // 转移主讲 + this.controlActionDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_linkmic_member_control_grant_speaker_confirm_title'), + content: $r('app.string.plvsa_linkmic_member_control_grant_speaker_confirm_content'), + onClickConfirm: (controller) => { + this.sdk.linkmicManager.grantSpeaker(this.viewer.viewerId!) + controller?.close() + this.controller?.close() + } + }), + customStyle: true + }) + this.controlActionDialog.open() + } else { + // 直接授予主讲 + this.sdk.linkmicManager.grantSpeaker(this.viewer.viewerId!) + this.controller?.close() + } + } + + private onClickFullScreen() { + this.pageDataBus.linkmicFullScreenViewer.setValue(this.viewer) + this.controller?.close() + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct MemberControlAction { + icon: Resource = lateInit() + name: Resource = lateInit() + + build() { + Column() { + Image(this.icon) + .width(30) + .height(30) + .objectFit(ImageFit.Contain) + Text(this.name) + .fontColor('#99ffffff') + .fontSize(14) + .margin({ + top: 8 + }) + } + .padding({ + top: 6, + bottom: 6 + }) + .margin({ + top: 6, + bottom: 6 + }) + } +} + +export class PLVSALinkMicMemberControlActionSwitcher { + readonly canShowMemberControlDialog: boolean + readonly showCameraControl: boolean + readonly showMicrophoneControl: boolean + readonly showHangupButton: boolean + readonly showSpeakerControl: boolean + + constructor( + sdk: PLVLiveSceneSDK, + viewer: PLVLinkMicViewer + ) { + const localIsTeacher = sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + const viewerIsSpecialUserType = PLVSocketUserBean.isSpecialType(viewer.viewerType) + const linkmicMode = sdk.linkmicManager.channelLinkMicMode.value ?? PLVLinkMicMode.AUDIO + + this.canShowMemberControlDialog = !localIsTeacher || !viewer.isMyself + this.showCameraControl = localIsTeacher && !viewer.isMyself && (linkmicMode === PLVLinkMicMode.VIDEO || viewerIsSpecialUserType) + this.showMicrophoneControl = localIsTeacher && !viewer.isMyself + this.showHangupButton = localIsTeacher && !viewer.isMyself + this.showSpeakerControl = localIsTeacher && !viewer.isMyself + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicViewerTimerLayout.ets b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicViewerTimerLayout.ets new file mode 100644 index 0000000..318d3a6 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/linkmic/widgets/PLVSALinkMicViewerTimerLayout.ets @@ -0,0 +1,38 @@ +import { PLVLinkMicViewer, PLVScheduledTask, PLVTimeUtils } from '@polyvharmony/live-scenes-sdk' +import { lateInit, seconds } from '@polyvharmony/media-player-sdk' + +@Component +export struct PLVSALinkMicViewerTimerLayout { + viewer: PLVLinkMicViewer = lateInit() + @State private durationMs: number = 0 + private timerTask: PLVScheduledTask | null = null + + aboutToAppear(): void { + this.timerTask = new PLVScheduledTask( + () => { + this.durationMs = Date.now() - this.viewer.linkmicStartTimestamp + }, + 0, + seconds(1).toMillis() + ) + this.timerTask.start() + } + + build() { + Row() { + Image($r('app.media.plvsa_linkmic_viewer_timer_icon')) + .width(10) + .height(10) + Text(PLVTimeUtils.generateTime(this.durationMs, true)) + .fontColor('#FFFFFF') + .fontSize(12) + .margin({ + left: 3 + }) + } + } + + aboutToDisappear(): void { + this.timerTask?.cancel() + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/member/PLVSAMemberLayout.ets b/scenes_streamerAlone/src/main/ets/components/member/PLVSAMemberLayout.ets new file mode 100644 index 0000000..1a1f4f7 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/member/PLVSAMemberLayout.ets @@ -0,0 +1,150 @@ +import { + PLVLiveSceneSDK, + PLVMemberChannelViewer, + PLVMemberErrorEvent, + PLVToastUtils +} from '@polyvharmony/live-scenes-sdk'; +import { lateInit, lazy, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { PLVSAMemberListDataSource } from './item/PLVSAMemberListDataSource'; +import { PLVSAMemberListItem } from './item/PLVSAMemberListItem'; +import { display } from '@kit.ArkUI'; +import { PLVSAPageDataBus } from '../../common/PLVSAPageDataBus'; + +@CustomDialog +export struct PLVSAMemberLayout { + controller: CustomDialogController = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + + aboutToAppear(): void { + this.pageDataBus.memberLayoutVisible.setValue(true) + } + + build() { + if (this.isPortrait()) { + PLVSAMemberLayoutPort() + } else { + PLVSAMemberLayoutLand() + } + } + + aboutToDisappear(): void { + this.pageDataBus.memberLayoutVisible.setValue(false) + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSAMemberLayoutPort { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly dataSource = lazy(() => new PLVSAMemberListDataSource(this.sdk.memberManager.channelViewers)) + @State private channelViewerCount: number = 0 + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.memberManager.channelViewerCount.observe(it => this.channelViewerCount = it) + .pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_member_online_count', this.channelViewerCount.toString())) + .fontSize(18) + .fontColor('#F0F1F5') + List() { + LazyForEach( + this.dataSource.value, + (channelViewer: PLVMemberChannelViewer) => { + PLVSAMemberListItem({ + viewer: channelViewer + }) + }, + (channelViewer: PLVMemberChannelViewer) => channelViewer.viewerId + ) + } + .width('100%') + .height(300) + .margin({ + top: 16 + }) + } + .alignItems(HorizontalAlign.Start) + .padding({ + left: 32, + right: 32, + top: 32 + }) + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + .backgroundColor('#2C2C2C') + } + + aboutToDisappear(): void { + this.dataSource.value.destroy() + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSAMemberLayoutLand { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly dataSource = lazy(() => new PLVSAMemberListDataSource(this.sdk.memberManager.channelViewers)) + @State private channelViewerCount: number = 0 + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.memberManager.channelViewerCount.observe(it => this.channelViewerCount = it) + .pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_member_online_count', this.channelViewerCount.toString())) + .fontSize(18) + .fontColor('#F0F1F5') + + List() { + LazyForEach( + this.dataSource.value, + (channelViewer: PLVMemberChannelViewer) => { + PLVSAMemberListItem({ + viewer: channelViewer + }) + }, + (channelViewer: PLVMemberChannelViewer) => channelViewer.viewerId + ) + } + .width('100%') + .layoutWeight(1) + .margin({ + top: 16 + }) + } + .width(400) + .height('100%') + .alignItems(HorizontalAlign.Start) + .padding({ + left: 32, + right: 32, + top: 32 + }) + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + .backgroundColor('#2C2C2C') + } + + aboutToDisappear(): void { + this.dataSource.value.destroy() + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} diff --git a/scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListDataSource.ets b/scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListDataSource.ets new file mode 100644 index 0000000..bd2c19e --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListDataSource.ets @@ -0,0 +1,38 @@ +import { PLVMemberChannelViewer } from '@polyvharmony/live-scenes-sdk'; +import { extendArray, MutableObserver, State } from '@polyvharmony/media-player-sdk'; + +export class PLVSAMemberListDataSource implements IDataSource { + private readonly listeners: DataChangeListener[] = [] + private readonly stateChannelViewers: State + private list: PLVMemberChannelViewer[] = [] + private observers: MutableObserver[] = [] + + constructor(stateChannelViewers: State) { + this.stateChannelViewers = stateChannelViewers + stateChannelViewers.observe(viewers => { + this.list = viewers + this.listeners.forEach(listener => listener.onDataReloaded()) + }).pushTo(this.observers) + } + + totalCount(): number { + return this.list.length + } + + getData(index: number): PLVMemberChannelViewer { + return this.list[index] + } + + registerDataChangeListener(listener: DataChangeListener): void { + this.listeners.push(listener) + } + + unregisterDataChangeListener(listener: DataChangeListener): void { + extendArray(this.listeners).remove_ext(listener) + } + + destroy() { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListItem.ets b/scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListItem.ets new file mode 100644 index 0000000..3ddffad --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/member/item/PLVSAMemberListItem.ets @@ -0,0 +1,446 @@ +import { + PLVLinkMicMode, + PLVLinkMicState, + PLVLiveSceneSDK, + PLVMemberChannelViewer, + PLVSocketUserBean, + PLVStreamerState, + PLVUserType +} from '@polyvharmony/live-scenes-sdk'; +import { + DerivedState, + isLiteralTrue, + isTextBlank, + isTextEmpty, + lateInit, + MutableObserver, + PLVMediaPlayerAppContext +} from '@polyvharmony/media-player-sdk'; +import { CircleShape } from '@kit.ArkUI'; +import { PLVSAConfirmDialog } from '../../../common/widget/PLVSAConfirmDialog'; + +@Component +export struct PLVSAMemberListItem { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + viewer: PLVMemberChannelViewer = lateInit() + @State actor: string | undefined = undefined + @State nickName: string = "" + @State nickLabelMyself: string = "" + @State isChannelOpenLinkMic: boolean = false + @State channelLinkMicMode: PLVLinkMicMode = PLVLinkMicMode.VIDEO + @State streamState: PLVStreamerState = PLVStreamerState.NOT_START + @State linkmicState: PLVLinkMicState = PLVLinkMicState.NoLinkMic + @State isVideoEnable: boolean = false + @State isAudioEnable: boolean = false + @State isSpeaker: boolean = false + @State isBan: boolean = false + @State morePopupVisible: boolean = false + private readonly hangupLinkMicDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_member_hang_up_linkmic_confirm_title'), + hasContent: false, + onClickConfirm: (controller) => { + this.sdk.linkmicManager.hangupViewerLinkMic(this.viewer.viewerId) + controller?.close() + } + }), + customStyle: true + }) + private readonly kickViewerDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_member_kick_confirm_title', this.viewer.viewerName.value), + content: $r('app.string.plvsa_member_kick_confirm_content'), + onClickConfirm: (controller) => { + this.sdk.memberManager.kickViewer(this.viewer.viewerId) + controller?.close() + } + }), + customStyle: true + }) + private readonly banViewerDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + title: $r('app.string.plvsa_member_ban_confirm_title', this.viewer.viewerName.value), + hasContent: false, + onClickConfirm: (controller) => { + this.sdk.memberManager.banViewer(this.viewer.viewerId) + controller?.close() + } + }), + customStyle: true + }) + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const isSpecialUserType = PLVSocketUserBean.isSpecialType(this.viewer.viewerType) + this.actor = isSpecialUserType ? this.viewer.viewerActor : undefined + this.nickLabelMyself = this.viewer.isMyself ? PLVMediaPlayerAppContext.getString($r('app.string.plvsa_chat_me'), "", "") : "" + this.viewer.viewerName.observe(it => this.nickName = it ?? "").pushTo(this.observers) + this.viewer.linkmicState.observe(it => this.linkmicState = it).pushTo(this.observers) + this.viewer.ban.observe(it => this.isBan = it).pushTo(this.observers) + this.sdk.linkmicManager.channelAllowRequestHandsUpLinkMic.observe(it => this.isChannelOpenLinkMic = it) + .pushTo(this.observers) + this.sdk.linkmicManager.channelLinkMicMode.observe(it => this.channelLinkMicMode = it) + .pushTo(this.observers) + this.sdk.streamerManager.streamerState.observe(it => this.streamState = it) + .pushTo(this.observers) + this.sdk.linkmicManager.channelMainViewLinkMicId.observe((mainViewLinkMicId) => { + this.isSpeaker = this.viewer.linkmicId !== undefined && this.viewer.linkmicId === mainViewLinkMicId + }).pushTo(this.observers) + const stateVideoEnable = new DerivedState(() => { + const linkmicViewer = (this.sdk.linkmicManager.channelLinkMicViewers.value ?? []) + .find(linkmicViewer => linkmicViewer.linkmicId === this.viewer.linkmicId) + return linkmicViewer?.isVideoEnable.value ?? false + }) + stateVideoEnable.observe(it => this.isVideoEnable = it).pushTo(this.observers) + const stateAudioEnable = new DerivedState(() => { + const linkmicViewer = (this.sdk.linkmicManager.channelLinkMicViewers.value ?? []) + .find(linkmicViewer => linkmicViewer.linkmicId === this.viewer.linkmicId) + return linkmicViewer?.isAudioEnable.value ?? false + }) + stateAudioEnable.observe(it => this.isAudioEnable = it).pushTo(this.observers) + } + + build() { + Row() { + // 头像 + Stack() { + Image(this.viewerAvatar()) + .width(44) + .height(44) + .clipShape(new CircleShape({ + width: 44, + height: 44 + })) + // 禁言角标 + if (this.isBan) { + Image($r('app.media.plvsa_member_list_item_ban_chat_icon')) + .width(20) + .height(20) + .translate({ + x: 4 + }) + } + } + .width(44) + .height(44) + .alignContent(Alignment.BottomEnd) + .margin({ + right: 12 + }) + + // 头衔 + if (!isTextEmpty(this.actor)) { + Text(this.actor) + .height(18) + .constraintSize({ + minWidth: 42 + }) + .fontSize(11) + .fontColor('#FFFFFF') + .textAlign(TextAlign.Center) + .padding({ + left: 3, + right: 3 + }) + .borderRadius(15) + .linearGradient({ + angle: 90, + colors: this.viewerActorBackground() + }) + .margin({ + right: 8 + }) + } + + // 昵称 + Text(this.nickName + this.nickLabelMyself) + .fontColor('#F0F1F5') + .fontSize(14) + .layoutWeight(1) + .maxLines(1) + .textOverflow({ + overflow: TextOverflow.Ellipsis + }) + .ellipsisMode(EllipsisMode.END) + + // 申请连麦举手图标 + if (this.isHandsUpIconVisible()) { + Image($r('app.media.plvsa_member_linkmic_hand_up_icon')) + .width(20) + .height(20) + .margin({ + right: 8 + }) + } + + // 连麦控制图标 + if (this.isLinkMicButtonVisible()) { + Image(this.linkmicButtonIcon()) + .width(32) + .height(32) + .onClick(() => this.onClickLinkMicButton()) + } + + // 更多菜单按钮 + if (this.isMoreButtonVisible()) { + Image($r('app.media.plvsa_member_more_icon')) + .width(32) + .height(32) + .margin({ + left: 20 + }) + .onClick(() => this.morePopupVisible = true) + .bindPopup(this.morePopupVisible, { + builder: this.moreButtonPopup, + placement: Placement.Top, + backgroundBlurStyle: BlurStyle.NONE, + popupColor: '#212121', + radius: 16, + onStateChange: (event) => { + this.morePopupVisible = event.isVisible + } + }) + } + } + .width('100%') + .height(68) + } + + private viewerAvatar(): string | Resource { + if (!isTextBlank(this.viewer.viewerAvatar)) { + return this.viewer.viewerAvatar as string + } + const isSpecialUser = PLVSocketUserBean.isSpecialType(this.viewer.viewerType) + if (isSpecialUser) { + return $r('app.media.plvsa_member_default_avatar_teacher') + } else { + return $r('app.media.plvsa_member_default_avatar_student') + } + } + + private viewerActorBackground(): [ResourceColor, number][] { + const viewerType = this.viewer.viewerType + if (viewerType === undefined) { + return [] + } + const linear = (start: ResourceColor, end: ResourceColor): [ResourceColor, number][] => [[start, 0], [end, 1]] + switch (viewerType) { + case PLVUserType.USERTYPE_TEACHER: + return linear('#FFA336', '#FFB95A') + case PLVUserType.USERTYPE_ASSISTANT: + return linear('#397ffe', '#73a1fe') + case PLVUserType.USERTYPE_MANAGER: + return linear('#32B6BF', '#35C4CF') + case PLVUserType.USERTYPE_GUEST: + default: + return linear('#FF2851', '#FE3182') + } + } + + private isHandsUpIconVisible(): boolean { + const isMyselfTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + const isViewerRequesting = this.linkmicState === PLVLinkMicState.Requesting + return isMyselfTeacher && isViewerRequesting + } + + private isLinkMicButtonVisible(): boolean { + const isMyselfTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + const isViewerUserTypeGuest = this.viewer.viewerType === PLVUserType.USERTYPE_GUEST + const isViewerUserTypeViewer = this.viewer.viewerType === PLVUserType.USERTYPE_VIEWER + const isLinkMicStrategyV2 = this.sdk.linkmicManager.isLinkMicStrategyV2.value ?? false + const isChannelAllowInviteLinkMic = isLiteralTrue(this.sdk.channelData.liveDetail?.inviteAudioEnabled) + const canInviteLinkMicV1 = !isLinkMicStrategyV2 + && isMyselfTeacher + && (this.isChannelOpenLinkMic || isViewerUserTypeGuest || isViewerUserTypeViewer) + && (isChannelAllowInviteLinkMic || isViewerUserTypeGuest || isViewerUserTypeViewer) + const canInviteLinkMicV2 = isLinkMicStrategyV2 + && isMyselfTeacher + && (isChannelAllowInviteLinkMic || isViewerUserTypeGuest || isViewerUserTypeViewer) + const canInviteLinkMic = canInviteLinkMicV1 || canInviteLinkMicV2 + + if (this.viewer.isMyself || !isMyselfTeacher || this.streamState !== PLVStreamerState.START) { + return false + } + if (this.linkmicState === PLVLinkMicState.NoLinkMic) { + return canInviteLinkMic + } else { + return true + } + } + + private linkmicButtonIcon(): Resource { + switch (this.linkmicState) { + case PLVLinkMicState.NoLinkMic: + case PLVLinkMicState.Requesting: + case PLVLinkMicState.WaitingResponse: + default: + return $r('app.media.plvsa_linkmic_button_to_open') + case PLVLinkMicState.Inviting: + return $r('app.media.plvsa_linkmic_waiting_response_anim') + case PLVLinkMicState.Joined: + return $r('app.media.plvsa_linkmic_button_to_close') + } + } + + private isMoreButtonVisible(): boolean { + const isMyselfTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + const isSpecialUserType = PLVSocketUserBean.isSpecialType(this.viewer.viewerType) + + if (this.viewer.isMyself || !isMyselfTeacher) { + return false + } + if (!isSpecialUserType) { + return true + } else { + return this.linkmicState === PLVLinkMicState.Joined + } + } + + @Builder + private moreButtonPopup() { + Column() { + // 摄像头控制 + if (this.linkmicState === PLVLinkMicState.Joined && this.channelLinkMicMode === PLVLinkMicMode.VIDEO) { + Row() { + Image(this.isVideoEnable ? $r('app.media.plvsa_more_camera_enable') : $r('app.media.plvsa_more_camera_disable')) + .width(44) + .height(44) + .padding(10) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_camera')) + .fontSize(14) + .fontColor('#F0F1F5') + } + .onClick(() => this.onClickControlCamera()) + } + // 麦克风控制 + if (this.linkmicState === PLVLinkMicState.Joined) { + Row() { + Image(this.isAudioEnable ? $r('app.media.plvsa_more_microphone_enable') : $r('app.media.plvsa_more_microphone_disable')) + .width(44) + .height(44) + .padding(10) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_microphone')) + .fontSize(14) + .fontColor('#F0F1F5') + } + .onClick(() => this.onClickControlMicrophone()) + } + // 主讲权限 + if (this.linkmicState === PLVLinkMicState.Joined && this.viewer.viewerType === PLVUserType.USERTYPE_GUEST) { + Row() { + Image($r('app.media.plvsa_linkmic_speaker_icon')) + .width(44) + .height(44) + .padding(10) + .objectFit(ImageFit.Contain) + Text(this.isSpeaker ? $r('app.string.plvsa_member_more_withdraw_speaker_permission') : $r('app.string.plvsa_member_more_grant_speaker_permission')) + .fontSize(14) + .fontColor('#F0F1F5') + } + .onClick(() => this.onClickSetSpeaker()) + } + // 踢出 + if (!PLVSocketUserBean.isSpecialType(this.viewer.viewerType)) { + Row() { + Image($r('app.media.plvsa_member_kick_out_icon')) + .width(44) + .height(44) + .padding(10) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_member_more_kick_out')) + .fontSize(14) + .fontColor('#F0F1F5') + } + .onClick(() => this.onClickKickViewer()) + } + // 禁言 + if (!PLVSocketUserBean.isSpecialType(this.viewer.viewerType)) { + Row() { + Image($r('app.media.plvsa_chatroom_ban_chat_icon')) + .width(44) + .height(44) + .padding(10) + .objectFit(ImageFit.Contain) + Text(this.isBan ? $r('app.string.plvsa_member_more_unban_chat') : $r('app.string.plvsa_member_more_ban_chat')) + .fontSize(14) + .fontColor('#F0F1F5') + } + .onClick(() => this.onClickBanViewer()) + } + } + .alignItems(HorizontalAlign.Start) + .constraintSize({ + minWidth: 137 + }) + .padding({ + left: 14, + right: 14, + top: 10, + bottom: 10 + }) + } + + private onClickLinkMicButton() { + const isMyselfTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + const isViewerUserTypeGuest = this.viewer.viewerType === PLVUserType.USERTYPE_GUEST + const isViewerUserTypeViewer = this.viewer.viewerType === PLVUserType.USERTYPE_VIEWER + const isLinkMicStrategyV2 = this.sdk.linkmicManager.isLinkMicStrategyV2.value ?? false + const isChannelAllowInviteLinkMic = isLiteralTrue(this.sdk.channelData.liveDetail?.inviteAudioEnabled) + const canInviteLinkMicV1 = !isLinkMicStrategyV2 + && isMyselfTeacher + && (this.isChannelOpenLinkMic || isViewerUserTypeGuest || isViewerUserTypeViewer) + && (isChannelAllowInviteLinkMic || isViewerUserTypeGuest || isViewerUserTypeViewer) + const canInviteLinkMicV2 = isLinkMicStrategyV2 + && isMyselfTeacher + && (isChannelAllowInviteLinkMic || isViewerUserTypeGuest || isViewerUserTypeViewer) + const canInviteLinkMic = canInviteLinkMicV1 || canInviteLinkMicV2 + const notNeedAnswer = !isChannelAllowInviteLinkMic && (isViewerUserTypeGuest || isViewerUserTypeViewer) + if (this.linkmicState === PLVLinkMicState.Requesting) { + this.sdk.linkmicManager.acceptViewerLinkMicRequest(this.viewer.viewerId) + } else if (this.linkmicState === PLVLinkMicState.Joined) { + this.hangupLinkMicDialogController.open() + } else if (canInviteLinkMic) { + this.sdk.linkmicManager.inviteViewerLinkMic(this.viewer.viewerId, !notNeedAnswer) + } + } + + private onClickControlCamera() { + this.sdk.linkmicManager.setViewerEnableCamera(this.viewer.viewerId, !this.isVideoEnable) + this.morePopupVisible = false + } + + private onClickControlMicrophone() { + this.sdk.linkmicManager.setViewerEnableMicrophone(this.viewer.viewerId, !this.isAudioEnable) + this.morePopupVisible = false + } + + private onClickSetSpeaker() { + if (this.isSpeaker) { + this.sdk.linkmicManager.revokeSpeaker(this.viewer.viewerId) + } else { + this.sdk.linkmicManager.grantSpeaker(this.viewer.viewerId) + } + this.morePopupVisible = false + } + + private onClickKickViewer() { + this.kickViewerDialogController.open() + this.morePopupVisible = false + } + + private onClickBanViewer() { + if (!this.isBan) { + this.banViewerDialogController.open() + } else { + this.sdk.memberManager.banViewer(this.viewer.viewerId, false) + } + this.morePopupVisible = false + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/misc/PLVSANetworkDisconnectMaskLayout.ets b/scenes_streamerAlone/src/main/ets/components/misc/PLVSANetworkDisconnectMaskLayout.ets new file mode 100644 index 0000000..838e607 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/misc/PLVSANetworkDisconnectMaskLayout.ets @@ -0,0 +1,132 @@ +import { componentUtils } from '@kit.ArkUI' +import { PLVLiveSceneSDK, PLVNetworkQuality } from '@polyvharmony/live-scenes-sdk' +import { derivedStateOf, lateInit, MutableObserver, Rect } from '@polyvharmony/media-player-sdk' +import { PLVSAPageDataBus } from '../../common/PLVSAPageDataBus' + +@Component +export struct PLVSANetworkDisconnectMaskLayout { + callbackOnTouchIntercept: (callback: (event: TouchEvent) => HitTestMode) => void = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private isVisible: boolean = false + private context: CanvasRenderingContext2D = new CanvasRenderingContext2D({ antialias: true }) + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.callbackOnTouchIntercept((event) => this.handleOnTouchIntercept(event)) + const networkDisconnectedState = derivedStateOf(() => { + const networkQuality = this.sdk.linkmicManager.linkmicNetworkQuality.value + if (networkQuality === PLVNetworkQuality.DISCONNECT) { + return true + } + if (networkQuality === PLVNetworkQuality.UNKNOWN) { + const networkStatistics = this.sdk.linkmicManager.linkmicNetworkStatistics.value + const delay = networkStatistics?.upDelayMs ?? 0 + if (delay < 0) { + return true + } + } + return false + }) + networkDisconnectedState.observe((disconnected) => { + this.isVisible = disconnected + }).pushTo(this.observers) + networkDisconnectedState.relayTo(this.pageDataBus.networkDisconnectedMaskVisible).pushTo(this.observers) + } + + build() { + if (this.isVisible) { + Stack() { + Canvas(this.context) + .width('100%') + .height('100%') + .onReady(() => { + this.drawMask() + }) + + Column() { + Image($r('app.media.plvsa_network_disconnect_mask_icon')) + .width(64) + .height(64) + + Text($r('app.string.plvsa_network_disconnect_mask_hint')) + .fontSize(16) + .fontColor('#FFFFFF') + .margin({ + top: 8 + }) + } + } + .width('100%') + .height('100%') + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } + + private drawMask() { + this.context.reset() + const path = new Path2D() + path.rect(0, 0, this.context.width, this.context.height) + this.pathCloseIcon(path) + this.pathNetworkStatusBar(path) + this.context.clip(path, 'evenodd') + this.context.fillStyle = '#99000000' + this.context.fillRect(0, 0, this.context.width, this.context.height) + } + + private pathCloseIcon(path: Path2D) { + const maskLayoutInfo = componentUtils.getRectangleById('plvsa_network_disconnect_mask_layout') + const closeIconInfo = componentUtils.getRectangleById('plvsa_status_bar_finish_stream_icon') + const offsetX = px2vp(closeIconInfo.screenOffset.x - maskLayoutInfo.screenOffset.x) + const offsetY = px2vp(closeIconInfo.screenOffset.y - maskLayoutInfo.screenOffset.y) + const radius = px2vp(closeIconInfo.size.width / 2) + path.arc(offsetX + radius, offsetY + radius, radius, 0, 2 * Math.PI) + } + + private pathNetworkStatusBar(outPath: Path2D) { + const maskLayoutInfo = componentUtils.getRectangleById('plvsa_network_disconnect_mask_layout') + const networkBarInfo = componentUtils.getRectangleById('plvsa_status_bar_network_bar') + const offsetX = px2vp(networkBarInfo.screenOffset.x - maskLayoutInfo.screenOffset.x) + const offsetY = px2vp(networkBarInfo.screenOffset.y - maskLayoutInfo.screenOffset.y) + const width = px2vp(networkBarInfo.size.width) + const height = px2vp(networkBarInfo.size.height) + const radius = 10 + const path = new Path2D() + path.moveTo(offsetX, offsetY + height / 2) + path.arcTo(offsetX, offsetY, offsetX + width / 2, offsetY, radius) + path.arcTo(offsetX + width, offsetY, offsetX + width, offsetY + height / 2, radius) + path.arcTo(offsetX + width, offsetY + height, offsetX + width / 2, offsetY + height, radius) + path.arcTo(offsetX, offsetY + height, offsetX, offsetY + height / 2, radius) + outPath.addPath(path) + } + + private handleOnTouchIntercept(event: TouchEvent): HitTestMode { + if (!this.isVisible) { + return HitTestMode.Transparent + } + if (this.isTouchView(event, 'plvsa_status_bar_finish_stream_icon') + || this.isTouchView(event, 'plvsa_status_bar_network_bar')) { + return HitTestMode.Transparent + } + return HitTestMode.Default + } + + private isTouchView(event: TouchEvent, id: string) { + const viewRect = (id: string) => { + const info = componentUtils.getRectangleById(id) + return new Rect({ + left: info.windowOffset.x, + top: info.windowOffset.y, + right: info.windowOffset.x + info.size.width, + bottom: info.windowOffset.y + info.size.height + }) + } + const x = vp2px(event.touches[0]?.windowX) + const y = vp2px(event.touches[0]?.windowY) + return viewRect(id).contains(x, y) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/PLVSAMoreLayout.ets b/scenes_streamerAlone/src/main/ets/components/more/PLVSAMoreLayout.ets new file mode 100644 index 0000000..afde009 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/PLVSAMoreLayout.ets @@ -0,0 +1,316 @@ +import { isLiteralTrue, lateInit, lazy } from '@polyvharmony/media-player-sdk'; +import { display } from '@kit.ArkUI'; +import { PLVSAMoreCameraEnableButton } from './widgets/PLVSAMoreCameraEnableButton'; +import { PLVSAMoreMicrophoneEnableButton } from './widgets/PLVSAMoreMicrophoneEnableButton'; +import { PLVSAMoreCameraFacingButton } from './widgets/PLVSAMoreCameraFacingButton'; +import { PLVSAMoreCameraMirrorButton } from './widgets/PLVSAMoreCameraMirrorButton'; +import { PLVSAMoreBitRateButton } from './widgets/PLVSAMoreBitRateButton'; +import { PLVSAMoreMixLayoutButton } from './widgets/PLVSAMoreMixLayoutButton'; +import { PLVSAMoreCloseRoomButton } from './widgets/PLVSAMoreCloseRoomButton'; +import { PLVSAMoreHangupAllLinkMicButton } from './widgets/PLVSAMoreHangupAllLinkMicButton'; +import { PLVSAMoreAllowLinkMicButton } from './widgets/PLVSAMoreAllowLinkMicButton'; +import { PLVSAMoreLinkMicSettingButton } from './widgets/PLVSAMoreLinkMicSettingButton'; +import { PLVSAMorePushDowngradeButton } from './widgets/PLVSAMorePushDowngradeButton'; +import { PLVLiveSceneSDK, PLVUserType } from '@polyvharmony/live-scenes-sdk'; +import { PLVSAMoreShareButton } from './widgets/PLVSAMoreShareButton'; + +@CustomDialog +export struct PLVSAMoreLayout { + controller: CustomDialogController = lateInit() + + build() { + if (this.isPortrait()) { + PLVSAMoreLayoutPort({ + controller: this.controller + }) + } else { + PLVSAMoreLayoutLand({ + controller: this.controller + }) + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSAMoreLayoutPort { + controller: CustomDialogController = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly switcher = lazy(() => new PLVSAMoreLayoutActionSwitcher(this.sdk)) + + build() { + Column() { + Text($r('app.string.plvsa_more_layout_title')) + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 25, + top: 32 + }) + Scroll() { + Grid() { + GridItem() { + PLVSAMoreCameraEnableButton() + } + + GridItem() { + PLVSAMoreMicrophoneEnableButton() + } + + GridItem() { + PLVSAMoreCameraFacingButton() + } + + GridItem() { + PLVSAMoreCameraMirrorButton() + } + + GridItem() { + PLVSAMoreBitRateButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + + if (this.switcher.value.showCloseRoomButton) { + GridItem() { + PLVSAMoreCloseRoomButton() + } + } + + if (this.switcher.value.showShareButton) { + GridItem() { + PLVSAMoreShareButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + } + + GridItem() { + PLVSAMorePushDowngradeButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + + if (this.switcher.value.showAllowLinkMicButton) { + GridItem() { + PLVSAMoreAllowLinkMicButton() + } + } + + if (this.switcher.value.showHangupAllLinkMicButton) { + GridItem() { + PLVSAMoreHangupAllLinkMicButton() + } + } + + if (this.switcher.value.showLinkMicSettingButton) { + GridItem() { + PLVSAMoreLinkMicSettingButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + } + + if (this.switcher.value.showMixLayoutButton) { + GridItem() { + PLVSAMoreMixLayoutButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + } + } + .columnsTemplate('1fr 1fr 1fr 1fr 1fr') + .rowsGap(12) + .padding({ + left: 25, + right: 25 + }) + } + .width('100%') + .layoutWeight(1) + .align(Alignment.TopStart) + .margin({ + top: 16 + }) + } + .width('100%') + .height(270) + .alignItems(HorizontalAlign.Start) + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + } +} + +@Component +struct PLVSAMoreLayoutLand { + controller: CustomDialogController = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly switcher = lazy(() => new PLVSAMoreLayoutActionSwitcher(this.sdk)) + + build() { + Column() { + Text($r('app.string.plvsa_more_layout_title')) + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 25, + top: 32 + }) + Scroll() { + Grid() { + GridItem() { + PLVSAMoreCameraEnableButton() + } + + GridItem() { + PLVSAMoreMicrophoneEnableButton() + } + + GridItem() { + PLVSAMoreCameraFacingButton() + } + + GridItem() { + PLVSAMoreCameraMirrorButton() + } + + GridItem() { + PLVSAMoreBitRateButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + + if (this.switcher.value.showCloseRoomButton) { + GridItem() { + PLVSAMoreCloseRoomButton() + } + } + + if (this.switcher.value.showShareButton) { + GridItem() { + PLVSAMoreShareButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + } + + GridItem() { + PLVSAMorePushDowngradeButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + + if (this.switcher.value.showAllowLinkMicButton) { + GridItem() { + PLVSAMoreAllowLinkMicButton() + } + } + + if (this.switcher.value.showHangupAllLinkMicButton) { + GridItem() { + PLVSAMoreHangupAllLinkMicButton() + } + } + + if (this.switcher.value.showLinkMicSettingButton) { + GridItem() { + PLVSAMoreLinkMicSettingButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + } + + if (this.switcher.value.showMixLayoutButton) { + GridItem() { + PLVSAMoreMixLayoutButton({ + onClicked: (origin) => { + this.controller.close() + origin() + } + }) + } + } + } + .columnsTemplate('1fr 1fr 1fr') + .rowsGap(12) + .padding({ + left: 25, + right: 25 + }) + } + .width('100%') + .layoutWeight(1) + .align(Alignment.TopStart) + .margin({ + top: 16 + }) + } + .width(240) + .height('100%') + .alignItems(HorizontalAlign.Start) + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + } +} + +export class PLVSAMoreLayoutActionSwitcher { + private readonly sdk: PLVLiveSceneSDK + readonly showCloseRoomButton: boolean + readonly showShareButton: boolean + readonly showAllowLinkMicButton: boolean + readonly showHangupAllLinkMicButton: boolean + readonly showLinkMicSettingButton: boolean + readonly showMixLayoutButton: boolean + readonly showResolutionRatioButton: boolean + + constructor(sdk: PLVLiveSceneSDK) { + this.sdk = sdk + const isTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + const isLinkMicStrategyV2 = this.sdk.linkmicManager.isLinkMicStrategyV2.value ?? false + + this.showCloseRoomButton = isTeacher + this.showShareButton = isLiteralTrue(this.sdk.channelData.liveDetail?.pushSharingEnabled) + this.showAllowLinkMicButton = isTeacher && isLinkMicStrategyV2 + this.showHangupAllLinkMicButton = isTeacher + this.showLinkMicSettingButton = isTeacher && isLinkMicStrategyV2 + this.showMixLayoutButton = isTeacher + this.showResolutionRatioButton = isTeacher && isLiteralTrue(this.sdk.channelData.streamerData?.appWebStartResolutionRatioEnabled) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreAllowLinkMicButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreAllowLinkMicButton.ets new file mode 100644 index 0000000..ee97bc7 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreAllowLinkMicButton.ets @@ -0,0 +1,52 @@ +import { PLVLiveSceneSDK, PLVToastUtils } from "@polyvharmony/live-scenes-sdk"; +import { lateInit, MutableObserver } from "@polyvharmony/media-player-sdk"; + +@Component +export struct PLVSAMoreAllowLinkMicButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private isOpenLinkMic: boolean = false + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.channelAllowRequestHandsUpLinkMic.observe(it => this.isOpenLinkMic = it).pushTo(this.observers) + } + + build() { + Column() { + Image(this.isOpenLinkMic ? $r('app.media.plvsa_more_allow_viewer_linkmic_active') : $r('app.media.plvsa_more_allow_viewer_linkmic_inactive')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_linkmic_viewer_raise_hand_text')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(async () => { + const toOpenLinkMic = !this.isOpenLinkMic + let success: boolean = false + if (toOpenLinkMic) { + success = await this.sdk.linkmicManager.openLinkMic() + } else { + success = await this.sdk.linkmicManager.closeLinkMic() + } + if (success) { + if (toOpenLinkMic) { + PLVToastUtils.shortShow($r('app.string.plvsa_linkmic_viewer_raise_hand_enable_toast')) + } else { + PLVToastUtils.shortShow($r('app.string.plvsa_linkmic_viewer_raise_hand_disable_toast')) + } + } else { + PLVToastUtils.shortShow($r('app.string.plvsa_linkmic_viewer_raise_hand_timeout_toast')) + } + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } + +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateButton.ets new file mode 100644 index 0000000..864d205 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateButton.ets @@ -0,0 +1,62 @@ +import { PLVLinkMicBitRate, PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { lateInit, MutableObserver, toRaw } from '@polyvharmony/media-player-sdk'; +import { PLVSAMoreBitRateSelectLayout } from './PLVSAMoreBitRateSelectLayout'; + +@Component +export struct PLVSAMoreBitRateButton { + iconPadding: number = 8 + onClicked: (origin: () => void) => void = (origin) => { + origin() + } + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly bitRateSelectController: CustomDialogController = new CustomDialogController({ + builder: PLVSAMoreBitRateSelectLayout(), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + @State private currentBitRate: PLVLinkMicBitRate = PLVLinkMicBitRate.STANDARD + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.currentBitRate.observe((bitRate) => this.currentBitRate = bitRate) + .pushTo(this.observers) + } + + build() { + Column() { + Image(this.bitRateIcon()) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text(this.currentBitRate.name) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.onClicked(() => { + this.bitRateSelectController.open() + }) + }) + } + + private bitRateIcon(): Resource { + switch (toRaw(this.currentBitRate)) { + case PLVLinkMicBitRate.STANDARD: + default: + return $r("app.media.plvsa_more_bitrate_icon_standard") + case PLVLinkMicBitRate.HIGH: + return $r("app.media.plvsa_more_bitrate_icon_high") + case PLVLinkMicBitRate.SUPER: + return $r("app.media.plvsa_more_bitrate_icon_super") + case PLVLinkMicBitRate.SUPER_HIGH: + return $r("app.media.plvsa_more_bitrate_icon_super_high") + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateSelectLayout.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateSelectLayout.ets new file mode 100644 index 0000000..7fc3a37 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreBitRateSelectLayout.ets @@ -0,0 +1,247 @@ +import { + PLVCommonConstants, + PLVLinkMicBitRate, + PLVLinkMicBitRateEncodeParam, + PLVLiveSceneSDK +} from '@polyvharmony/live-scenes-sdk' +import { lateInit, MutableObserver, toRaw } from '@polyvharmony/media-player-sdk' +import { PLVSAPreferenceCardView } from '../../../common/widget/PLVSAPreferenceCardView' +import { display } from '@kit.ArkUI' +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus' + +@CustomDialog +export struct PLVSAMoreBitRateSelectLayout { + controller: CustomDialogController = lateInit() + + build() { + if (this.isPortrait()) { + PLVSAMoreBitRateSelectLayoutPort({ + closeController: () => { + this.controller.close() + } + }) + } else { + PLVSAMoreBitRateSelectLayoutLand({ + closeController: () => { + this.controller.close() + } + }) + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSAMoreBitRateSelectLayoutPort { + closeController: () => void = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private currentBitRate: PLVLinkMicBitRate = PLVLinkMicBitRate.STANDARD + @State private supportBitRateEncodeParam: PLVLinkMicBitRateEncodeParam[] = [] + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.currentBitRate.observe(it => this.currentBitRate = it) + .pushTo(this.observers) + this.sdk.streamerManager.channelSupportBitRateEncodeParams.observe(it => this.supportBitRateEncodeParam = it) + .pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_more_bitrate_select_title')) + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 32, + top: 32 + }) + + Scroll() { + Column() { + ForEach( + this.supportBitRateEncodeParam, + (encodeParam: PLVLinkMicBitRateEncodeParam) => { + PLVSAMoreBitRateSelectItem({ + encodeParam: encodeParam, + selected: encodeParam.bitRate === toRaw(this.currentBitRate) + }) + .margin({ + left: 32, + right: 32, + top: 6, + bottom: 6 + }) + .onClick(() => { + const selected = encodeParam.bitRate === toRaw(this.currentBitRate) + if (!selected) { + this.sdk.streamerManager.setBitRate(encodeParam.bitRate) + this.pageDataBus.recoverSetting.update({ + bitRateIndex: encodeParam.bitRate.index + }) + this.closeController() + } + }) + }, + (encodeParam: PLVLinkMicBitRateEncodeParam) => encodeParam.bitRate.index.toString() + ) + + Blank().height(12) + } + } + .width('100%') + .height(300) + .align(Alignment.Top) + .scrollable(ScrollDirection.Vertical) + .scrollBar(BarState.Off) + .margin({ + top: 26 + }) + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSAMoreBitRateSelectLayoutLand { + closeController: () => void = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private currentBitRate: PLVLinkMicBitRate = PLVLinkMicBitRate.STANDARD + @State private supportBitRateEncodeParam: PLVLinkMicBitRateEncodeParam[] = [] + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.currentBitRate.observe(it => this.currentBitRate = it) + .pushTo(this.observers) + this.sdk.streamerManager.channelSupportBitRateEncodeParams.observe(it => this.supportBitRateEncodeParam = it) + .pushTo(this.observers) + } + + build() { + RelativeContainer() { + Text($r('app.string.plvsa_more_bitrate_select_title')) + .id('plvsa_more_bitrate_select_title') + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 32, + top: 32 + }) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + + Scroll() { + Column() { + ForEach( + this.supportBitRateEncodeParam, + (encodeParam: PLVLinkMicBitRateEncodeParam) => { + PLVSAMoreBitRateSelectItem({ + encodeParam: encodeParam, + selected: encodeParam.bitRate === toRaw(this.currentBitRate) + }) + .margin({ + left: 32, + right: 32, + top: 6, + bottom: 6 + }) + .onClick(() => { + const selected = encodeParam.bitRate === toRaw(this.currentBitRate) + if (!selected) { + this.sdk.streamerManager.setBitRate(encodeParam.bitRate) + this.pageDataBus.recoverSetting.update({ + bitRateIndex: encodeParam.bitRate.index + }) + this.closeController() + } + }) + }, + (encodeParam: PLVLinkMicBitRateEncodeParam) => encodeParam.bitRate.index.toString() + ) + + Blank().height(12) + } + } + .id('plvsa_more_bitrate_select_container') + .width('100%') + .align(Alignment.Top) + .scrollable(ScrollDirection.Vertical) + .scrollBar(BarState.Off) + .margin({ + top: 26 + }) + .alignRules({ + top: { anchor: 'plvsa_more_bitrate_select_title', align: VerticalAlign.Bottom }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + } + .width(304) + .height('100%') + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSAMoreBitRateSelectItem { + encodeParam: PLVLinkMicBitRateEncodeParam = lateInit() + @Prop selected: boolean = false + + build() { + PLVSAPreferenceCardView({ + slot: () => { + this.bitRateDescriptionContent() + }, + selected: this.selected + }) + } + + @Builder + private bitRateDescriptionContent() { + Column() { + Text(this.encodeParam.bitRate.name) + .fontSize(16) + .fontColor('#F0F1F5') + Text($r('app.string.plvsa_more_bitrate_description_text', `${this.encodeParam.videoWidth}p`, `${this.encodeParam.videoBitrate}kbps`, `${this.encodeParam.videoFps}fps`)) + .fontSize(12) + .fontColor('#99F0F1F5') + .margin({ + top: 4 + }) + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .padding({ + left: 20, + right: 20, + top: 12, + bottom: 12 + }) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraEnableButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraEnableButton.ets new file mode 100644 index 0000000..d5fab7f --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraEnableButton.ets @@ -0,0 +1,45 @@ +import { PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { DerivedState, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus'; + +@Component +export struct PLVSAMoreCameraEnableButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private enable: boolean = true + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const localVideoEnable = new DerivedState(() => { + return this.sdk.linkmicManager.localLinkMicViewer.value?.isVideoEnable?.value ?? false + }) + localVideoEnable.observe((videoEnable) => this.enable = videoEnable).pushTo(this.observers) + } + + build() { + Column() { + Image(this.enable ? $r('app.media.plvsa_more_camera_enable') : $r('app.media.plvsa_more_camera_disable')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_camera')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + const toEnable = !this.enable + this.sdk.linkmicManager.enableCamera(toEnable) + this.pageDataBus.recoverSetting.update({ + isEnableCamera: toEnable + }) + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraFacingButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraFacingButton.ets new file mode 100644 index 0000000..c2a525f --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraFacingButton.ets @@ -0,0 +1,49 @@ +import { PLVLinkMicCameraFacing, PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { DerivedState, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus'; + +@Component +export struct PLVSAMoreCameraFacingButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private enable: boolean = true + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const localVideoEnable = new DerivedState(() => { + return this.sdk.linkmicManager.localLinkMicViewer.value?.isVideoEnable?.value ?? false + }) + localVideoEnable.observe((videoEnable) => this.enable = videoEnable).pushTo(this.observers) + } + + build() { + Column() { + Image(this.enable ? $r('app.media.plvsa_more_camera_facing_enable') : $r('app.media.plvsa_more_camera_facing_disable')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_camera_facing_switch')) + .fontColor(this.enable ? "#FFFFFF" : "#99FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .enabled(this.enable) + .onClick(() => { + this.sdk.linkmicManager.switchCamera() + const newFacingFront = this.sdk.linkmicManager.cameraFacing.value === PLVLinkMicCameraFacing.FRONT + if (!newFacingFront) { + this.sdk.linkmicManager.setLocalMirror(false) + } + this.pageDataBus.recoverSetting.update({ + isFrontCamera: newFacingFront + }) + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraMirrorButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraMirrorButton.ets new file mode 100644 index 0000000..cfd2da6 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCameraMirrorButton.ets @@ -0,0 +1,57 @@ +import { PLVLinkMicCameraFacing, PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { DerivedState, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; + +@Component +export struct PLVSAMoreCameraMirrorButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private enable: boolean = true + @State private isMirror: boolean = false + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const mirrorEnable = new DerivedState(() => { + const videoEnable = this.sdk.linkmicManager.localLinkMicViewer.value?.isVideoEnable?.value ?? false + const cameraFacingFront = this.sdk.linkmicManager.cameraFacing.value === PLVLinkMicCameraFacing.FRONT + return videoEnable && cameraFacingFront + }) + mirrorEnable.observe((mirrorEnable) => this.enable = mirrorEnable).pushTo(this.observers) + this.sdk.linkmicManager.renderMirror.observe((isMirror) => this.isMirror = isMirror) + .pushTo(this.observers) + } + + build() { + Column() { + Image(this.mirrorIcon()) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_camera_mirror')) + .fontColor(this.enable ? "#FFFFFF" : "#99FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .enabled(this.enable) + .onClick(() => { + this.sdk.linkmicManager.setLocalMirror(!this.isMirror) + }) + } + + private mirrorIcon(): Resource { + if (!this.enable) { + return $r('app.media.plvsa_more_camera_mirror_disable') + } else { + if (this.isMirror) { + return $r('app.media.plvsa_more_camera_mirror_enable_on') + } else { + return $r('app.media.plvsa_more_camera_mirror_enable_off') + } + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCloseRoomButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCloseRoomButton.ets new file mode 100644 index 0000000..ab8e414 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreCloseRoomButton.ets @@ -0,0 +1,41 @@ +import { PLVLiveSceneSDK, PLVToastUtils } from "@polyvharmony/live-scenes-sdk" +import { lateInit } from "@polyvharmony/media-player-sdk" + +@Component +export struct PLVSAMoreCloseRoomButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private isCloseRoom: boolean = false + + aboutToAppear(): void { + this.isCloseRoom = this.sdk.chatroomManager.isCloseRoom + this.sdk.chatroomManager.eventNotify.on('close_room', this.onCloseRoomEvent) + } + + build() { + Column() { + Image($r('app.media.plvsa_more_close_room_icon')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text(this.isCloseRoom ? $r('app.string.plvsa_chat_cancel_close_room_text') : $r('app.string.plvsa_chat_close_room_text')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.sdk.chatroomManager.switchCloseRoom() + }) + } + + private readonly onCloseRoomEvent = (isCloseRoom: boolean) => { + this.isCloseRoom = isCloseRoom + PLVToastUtils.shortShow(isCloseRoom ? $r('app.string.plvsa_chat_close_room_toast') : $r('app.string.plvsa_chat_cancel_close_room_toast')) + } + + aboutToDisappear(): void { + this.sdk.chatroomManager.eventNotify.off('close_room', this.onCloseRoomEvent) + } + +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreHangupAllLinkMicButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreHangupAllLinkMicButton.ets new file mode 100644 index 0000000..7660d01 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreHangupAllLinkMicButton.ets @@ -0,0 +1,53 @@ +import { PLVLiveSceneSDK, PLVToastUtils } from '@polyvharmony/live-scenes-sdk' +import { lateInit, MutableObserver } from '@polyvharmony/media-player-sdk' +import { PLVSAConfirmDialog } from '../../../common/widget/PLVSAConfirmDialog' + +@Component +export struct PLVSAMoreHangupAllLinkMicButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly hangupAllLinkMicConfirmDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + content: $r('app.string.plvsa_linkmic_hang_up_all_confirm_content'), + onClickConfirm: (controller) => { + this.sdk.linkmicManager.hangupAllViewersLinkMic() + PLVToastUtils.shortShow($r('app.string.plvsa_linkmic_hang_up_all_toast')) + controller?.close() + } + }), + customStyle: true + }) + @State private enable: boolean = true + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.channelLinkMicViewers.observe(viewers => { + const hasOtherLinkMicViewer = viewers.some(it => it.linkmicId !== this.sdk.channelData.linkmicId) + this.enable = hasOtherLinkMicViewer + }).pushTo(this.observers) + } + + build() { + Column() { + Image($r('app.media.plvsa_more_hang_up_viewer_linkmic_icon')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_linkmic_hang_up_all_text')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .enabled(this.enable) + .opacity(this.enable ? 1 : 0.6) + .onClick(() => { + this.hangupAllLinkMicConfirmDialog.open() + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingButton.ets new file mode 100644 index 0000000..8574ac1 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingButton.ets @@ -0,0 +1,34 @@ +import { PLVSAMoreLinkMicSettingLayout } from './PLVSAMoreLinkMicSettingLayout' + +@Component +export struct PLVSAMoreLinkMicSettingButton { + iconPadding: number = 8 + onClicked: (origin: () => void) => void = (origin) => { + origin() + } + private readonly linkmicSettingDialog = new CustomDialogController({ + builder: PLVSAMoreLinkMicSettingLayout(), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + build() { + Column() { + Image($r('app.media.plvsa_more_linkmic_setting_icon')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_linkmic_setting_text')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.onClicked(() => { + this.linkmicSettingDialog.open() + }) + }) + } + +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingLayout.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingLayout.ets new file mode 100644 index 0000000..714a00b --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreLinkMicSettingLayout.ets @@ -0,0 +1,145 @@ +import { lateInit, MutableObserver } from "@polyvharmony/media-player-sdk"; +import { display } from "@kit.ArkUI"; +import { PLVLinkMicMode, PLVLiveSceneSDK, PLVUserType } from "@polyvharmony/live-scenes-sdk"; +import { PLVSAConfirmDialog } from "../../../common/widget/PLVSAConfirmDialog"; + +@CustomDialog +export struct PLVSAMoreLinkMicSettingLayout { + controller: CustomDialogController = lateInit() + + build() { + PLVSAMoreLinkMicSettingLayoutPort() + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } + +} + +@Component +struct PLVSAMoreLinkMicSettingLayoutPort { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private linkmicMode: PLVLinkMicMode = PLVLinkMicMode.AUDIO + private hangupViewerBeforeSwitchLinkMicDialog: CustomDialogController | null = null + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.channelLinkMicMode.observe(it => this.linkmicMode = it).pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_linkmic_setting_text')) + .fontSize(18) + .fontColor('#F0F1F5') + + Text($r('app.string.plvsa_linkmic_setting_default_linkmic_type')) + .fontSize(12) + .fontColor('#99F0F1F5') + .margin({ + top: 32 + }) + + Row(){ + Column() { + Text($r('app.string.plvsa_linkmic_setting_linkmic_type_audio')) + .fontSize(14) + .fontColor(this.linkmicMode === PLVLinkMicMode.AUDIO ? '#4399FF' : '#F0F1F5') + if (this.linkmicMode === PLVLinkMicMode.AUDIO) { + Circle() + .width(4) + .height(4) + .fill('#4399FF') + .margin({ + top: 2 + }) + } + } + .onClick(() => this.onClickSwitchLinkMicMode(PLVLinkMicMode.AUDIO)) + + Column() { + Text($r('app.string.plvsa_linkmic_setting_linkmic_type_video')) + .fontSize(14) + .fontColor(this.linkmicMode === PLVLinkMicMode.VIDEO ? '#4399FF' : '#F0F1F5') + if (this.linkmicMode === PLVLinkMicMode.VIDEO) { + Circle() + .width(4) + .height(4) + .fill('#4399FF') + .margin({ + top: 2 + }) + } + } + .margin({ + left: 32 + }) + .onClick(() => this.onClickSwitchLinkMicMode(PLVLinkMicMode.VIDEO)) + } + .alignItems(VerticalAlign.Top) + .margin({ + top: 14 + }) + + Text($r('app.string.plvsa_linkmic_setting_switch_hint')) + .fontSize(12) + .fontColor('#878B93') + .margin({ + top: 12 + }) + + Blank() + + Text($r('app.string.plvsa_linkmic_setting_default_setting_hint')) + .fontSize(12) + .fontColor('#99F0F1F5') + } + .width('100%') + .height(426) + .alignItems(HorizontalAlign.Start) + .padding({ + top: 32, + left: 32, + right: 32, + bottom: 24 + }) + .backgroundColor('#2C2C2C') + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + } + + private onClickSwitchLinkMicMode(mode: PLVLinkMicMode) { + if (mode === this.linkmicMode) { + return + } + const hasLinkMicViewer = (this.sdk.linkmicManager.channelLinkMicViewers.value ?? []) + .filter(it => it.viewerType !== PLVUserType.USERTYPE_TEACHER) + .length > 0 + if (hasLinkMicViewer) { + this.hangupViewerBeforeSwitchLinkMicDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + content: $r('app.string.plvsa_linkmic_setting_switch_type_hang_up_viewer_dialog_content'), + confirmText: $r('app.string.plvsa_linkmic_setting_switch_type_hang_up_viewer_dialog_confirm'), + onClickConfirm: (controller) => { + this.sdk.linkmicManager.setLinkMicMode(mode) + controller?.close() + } + }), + customStyle: true + }) + this.hangupViewerBeforeSwitchLinkMicDialog.open() + } else { + this.sdk.linkmicManager.setLinkMicMode(mode) + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } + +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMicrophoneEnableButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMicrophoneEnableButton.ets new file mode 100644 index 0000000..cb73936 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMicrophoneEnableButton.ets @@ -0,0 +1,39 @@ +import { PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { DerivedState, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; + +@Component +export struct PLVSAMoreMicrophoneEnableButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private enable: boolean = true + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const localAudioEnable = new DerivedState(() => { + return this.sdk.linkmicManager.localLinkMicViewer.value?.isAudioEnable?.value ?? false + }) + localAudioEnable.observe((audioEnable) => this.enable = audioEnable).pushTo(this.observers) + } + + build() { + Column() { + Image(this.enable ? $r('app.media.plvsa_more_microphone_enable') : $r('app.media.plvsa_more_microphone_disable')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_microphone')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.sdk.linkmicManager.enableMicrophone(!this.enable) + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutButton.ets new file mode 100644 index 0000000..37acb69 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutButton.ets @@ -0,0 +1,33 @@ +import { PLVSAMoreMixLayoutSelectLayout } from './PLVSAMoreMixLayoutSelectLayout'; + +@Component +export struct PLVSAMoreMixLayoutButton { + iconPadding: number = 8 + onClicked: (origin: () => void) => void = (origin) => { + origin() + } + private readonly mixLayoutSelectController: CustomDialogController = new CustomDialogController({ + builder: PLVSAMoreMixLayoutSelectLayout(), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + build() { + Column() { + Image($r('app.media.plvsa_more_mix_layout_icon')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_mix_layout')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.onClicked(() => { + this.mixLayoutSelectController.open() + }) + }) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutSelectLayout.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutSelectLayout.ets new file mode 100644 index 0000000..406cd53 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreMixLayoutSelectLayout.ets @@ -0,0 +1,244 @@ +import { lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { display } from '@kit.ArkUI'; +import { PLVLiveSceneSDK, PLVStreamerMixLayoutType } from '@polyvharmony/live-scenes-sdk'; + +@CustomDialog +export struct PLVSAMoreMixLayoutSelectLayout { + controller: CustomDialogController = lateInit() + + build() { + if (this.isPortrait()) { + PLVSAMoreMixLayoutSelectLayoutPort({ + closeController: () => { + this.controller.close() + } + }) + } else { + PLVSAMoreMixLayoutSelectLayoutLand({ + closeController: () => { + this.controller.close() + } + }) + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSAMoreMixLayoutSelectLayoutPort { + closeController: () => void = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private currentMixLayoutType: PLVStreamerMixLayoutType = PLVStreamerMixLayoutType.TILE + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.mixLayoutType.observe(it => this.currentMixLayoutType = it) + .pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_more_mix_layout_select_title')) + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 32, + top: 32 + }) + + Row() { + Text($r('app.string.plvsa_more_mix_layout_type_speaker')) + .width(88) + .height(32) + .textAlign(TextAlign.Center) + .fontColor('#FFFFFF') + .fontSize(14) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: this.isSelected(PLVStreamerMixLayoutType.SPEAKER) + ? [['#0080FF', 0], ['#3399FF', 1]] + : [['#33FFFFFF', 0], ['#33FFFFFF', 1]] + }) + .onClick(() => { + this.sdk.streamerManager.setMixLayoutType(PLVStreamerMixLayoutType.SPEAKER) + this.closeController() + }) + Blank() + Text($r('app.string.plvsa_more_mix_layout_type_tile')) + .width(88) + .height(32) + .textAlign(TextAlign.Center) + .fontColor('#FFFFFF') + .fontSize(14) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: this.isSelected(PLVStreamerMixLayoutType.TILE) + ? [['#0080FF', 0], ['#3399FF', 1]] + : [['#33FFFFFF', 0], ['#33FFFFFF', 1]] + }) + .onClick(() => { + this.sdk.streamerManager.setMixLayoutType(PLVStreamerMixLayoutType.TILE) + this.closeController() + }) + Blank() + Text($r('app.string.plvsa_more_mix_layout_type_single')) + .width(88) + .height(32) + .textAlign(TextAlign.Center) + .fontColor('#FFFFFF') + .fontSize(14) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: this.isSelected(PLVStreamerMixLayoutType.SINGLE) + ? [['#0080FF', 0], ['#3399FF', 1]] + : [['#33FFFFFF', 0], ['#33FFFFFF', 1]] + }) + .onClick(() => { + this.sdk.streamerManager.setMixLayoutType(PLVStreamerMixLayoutType.SINGLE) + this.closeController() + }) + } + .width('100%') + .padding({ + left: 32, + right: 32 + }) + .margin({ + top: 32 + }) + } + .width('100%') + .height(214) + .alignItems(HorizontalAlign.Start) + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + + } + + private isSelected(mixLayoutType: PLVStreamerMixLayoutType): boolean { + return this.currentMixLayoutType === mixLayoutType + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSAMoreMixLayoutSelectLayoutLand { + closeController: () => void = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private currentMixLayoutType: PLVStreamerMixLayoutType = PLVStreamerMixLayoutType.TILE + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.mixLayoutType.observe(it => this.currentMixLayoutType = it) + .pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_more_mix_layout_select_title')) + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 32, + top: 32 + }) + + Column() { + Text($r('app.string.plvsa_more_mix_layout_type_speaker')) + .width(88) + .height(32) + .textAlign(TextAlign.Center) + .fontColor('#FFFFFF') + .fontSize(14) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: this.isSelected(PLVStreamerMixLayoutType.SPEAKER) + ? [['#0080FF', 0], ['#3399FF', 1]] + : [['#33FFFFFF', 0], ['#33FFFFFF', 1]] + }) + .onClick(() => { + this.sdk.streamerManager.setMixLayoutType(PLVStreamerMixLayoutType.SPEAKER) + this.closeController() + }) + Blank().height(24) + Text($r('app.string.plvsa_more_mix_layout_type_tile')) + .width(88) + .height(32) + .textAlign(TextAlign.Center) + .fontColor('#FFFFFF') + .fontSize(14) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: this.isSelected(PLVStreamerMixLayoutType.TILE) + ? [['#0080FF', 0], ['#3399FF', 1]] + : [['#33FFFFFF', 0], ['#33FFFFFF', 1]] + }) + .onClick(() => { + this.sdk.streamerManager.setMixLayoutType(PLVStreamerMixLayoutType.TILE) + this.closeController() + }) + Blank().height(24) + Text($r('app.string.plvsa_more_mix_layout_type_single')) + .width(88) + .height(32) + .textAlign(TextAlign.Center) + .fontColor('#FFFFFF') + .fontSize(14) + .borderRadius(18) + .linearGradient({ + angle: 90, + colors: this.isSelected(PLVStreamerMixLayoutType.SINGLE) + ? [['#0080FF', 0], ['#3399FF', 1]] + : [['#33FFFFFF', 0], ['#33FFFFFF', 1]] + }) + .onClick(() => { + this.sdk.streamerManager.setMixLayoutType(PLVStreamerMixLayoutType.SINGLE) + this.closeController() + }) + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .padding({ + left: 32, + right: 32 + }) + .margin({ + top: 32 + }) + } + .width(214) + .height('100%') + .alignItems(HorizontalAlign.Start) + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + + } + + private isSelected(mixLayoutType: PLVStreamerMixLayoutType): boolean { + return this.currentMixLayoutType === mixLayoutType + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreOrientationButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreOrientationButton.ets new file mode 100644 index 0000000..ab40411 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreOrientationButton.ets @@ -0,0 +1,48 @@ +import { PLVLiveSceneSDK, PLVPushOrientation } from '@polyvharmony/live-scenes-sdk'; +import { lateInit } from '@polyvharmony/media-player-sdk'; +import { common } from '@kit.AbilityKit'; +import { display, window } from '@kit.ArkUI'; +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus'; + +@Component +export struct PLVSAMoreOrientationButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private context = getContext() as common.UIAbilityContext + + aboutToAppear(): void { + + } + + build() { + Column() { + Image($r('app.media.plvsa_more_orientation_icon')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_orientation')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(async () => { + const orientation = display.getDefaultDisplaySync().orientation + const isPortrait = orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + const nextIsPortrait = !isPortrait + const nextWindowOrientation = nextIsPortrait ? window.Orientation.PORTRAIT : window.Orientation.LANDSCAPE + const nextPushOrientation = nextIsPortrait ? PLVPushOrientation.PORTRAIT : PLVPushOrientation.LANDSCAPE + const windowInstance = await window.getLastWindow(this.context) + windowInstance.setPreferredOrientation(nextWindowOrientation) + this.sdk.streamerManager.setPushOrientation(nextPushOrientation) + this.pageDataBus.recoverSetting.update({ + isPortrait: nextIsPortrait + }) + }) + } + + aboutToDisappear(): void { + + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeButton.ets new file mode 100644 index 0000000..9b16554 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeButton.ets @@ -0,0 +1,33 @@ +import { PLVSAMorePushDowngradeLayout } from './PLVSAMorePushDowngradeLayout' + +@Component +export struct PLVSAMorePushDowngradeButton { + iconPadding: number = 8 + onClicked: (origin: () => void) => void = (origin) => { + origin() + } + private readonly controller = new CustomDialogController({ + builder: PLVSAMorePushDowngradeLayout(), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + build() { + Column() { + Image($r('app.media.plvsa_more_push_downgrade_preference_icon')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_push_downgrade_preference_title')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.onClicked(() => { + this.controller.open() + }) + }) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeLayout.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeLayout.ets new file mode 100644 index 0000000..482720a --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMorePushDowngradeLayout.ets @@ -0,0 +1,226 @@ +import { PLVLiveSceneSDK, PLVPushDowngradePreference } from '@polyvharmony/live-scenes-sdk'; +import { lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { PLVSAPreferenceCardView } from '../../../common/widget/PLVSAPreferenceCardView'; +import { display } from '@kit.ArkUI'; + +@CustomDialog +export struct PLVSAMorePushDowngradeLayout { + controller: CustomDialogController = lateInit() + + build() { + if (this.isPortrait()) { + PLVSAMorePushDowngradeLayoutPort() + } else { + PLVSAMorePushDowngradeLayoutLand() + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSAMorePushDowngradeLayoutPort { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private currentPreference: PLVPushDowngradePreference = PLVPushDowngradePreference.PREFER_BETTER_QUALITY + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.pushDowngradePreference.observe(it => this.currentPreference = it) + .pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_push_downgrade_preference_title')) + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 32, + top: 32 + }) + + PLVSAPreferenceCardView({ + slot: () => { + this.PreferenceDescriptionColumn( + $r('app.string.plvsa_push_downgrade_quality_title'), + $r('app.string.plvsa_push_downgrade_quality_desc') + ) + }, + selected: this.currentPreference === PLVPushDowngradePreference.PREFER_BETTER_QUALITY + }) + .onClick(() => { + this.sdk.streamerManager.setPushDowngradePreference(PLVPushDowngradePreference.PREFER_BETTER_QUALITY) + }) + .width('calc(100% - 32vp)') + .margin({ + top: 30, + left: 16, + right: 16 + }) + + PLVSAPreferenceCardView({ + slot: () => { + this.PreferenceDescriptionColumn( + $r('app.string.plvsa_push_downgrade_fluency_title'), + $r('app.string.plvsa_push_downgrade_fluency_desc') + ) + }, + selected: this.currentPreference === PLVPushDowngradePreference.PREFER_BETTER_FLUENCY + }) + .onClick(() => { + this.sdk.streamerManager.setPushDowngradePreference(PLVPushDowngradePreference.PREFER_BETTER_FLUENCY) + }) + .width('calc(100% - 32vp)') + .margin({ + top: 12, + left: 16, + right: 16 + }) + } + .width('100%') + .height(350) + .alignItems(HorizontalAlign.Start) + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + } + + @Builder + private PreferenceDescriptionColumn( + title: Resource, + desc: Resource + ) { + Column() { + Text(title) + .fontColor('#F0F1F5') + .fontSize(16) + .fontWeight(FontWeight.Bold) + Text(desc) + .fontColor('#99F0F1F5') + .fontSize(12) + .margin({ + top: 4 + }) + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .padding({ + top: 12, + bottom: 12, + left: 20, + right: 20 + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSAMorePushDowngradeLayoutLand { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private currentPreference: PLVPushDowngradePreference = PLVPushDowngradePreference.PREFER_BETTER_QUALITY + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.pushDowngradePreference.observe(it => this.currentPreference = it) + .pushTo(this.observers) + } + + build() { + Column() { + Text($r('app.string.plvsa_push_downgrade_preference_title')) + .fontColor('#F0F1F5') + .fontSize(18) + .margin({ + left: 32, + top: 32 + }) + + PLVSAPreferenceCardView({ + slot: () => { + this.PreferenceDescriptionColumn( + $r('app.string.plvsa_push_downgrade_quality_title'), + $r('app.string.plvsa_push_downgrade_quality_desc') + ) + }, + selected: this.currentPreference === PLVPushDowngradePreference.PREFER_BETTER_QUALITY + }) + .onClick(() => { + this.sdk.streamerManager.setPushDowngradePreference(PLVPushDowngradePreference.PREFER_BETTER_QUALITY) + }) + .width('calc(100% - 32vp)') + .margin({ + top: 30, + left: 16, + right: 16 + }) + + PLVSAPreferenceCardView({ + slot: () => { + this.PreferenceDescriptionColumn( + $r('app.string.plvsa_push_downgrade_fluency_title'), + $r('app.string.plvsa_push_downgrade_fluency_desc') + ) + }, + selected: this.currentPreference === PLVPushDowngradePreference.PREFER_BETTER_FLUENCY + }) + .onClick(() => { + this.sdk.streamerManager.setPushDowngradePreference(PLVPushDowngradePreference.PREFER_BETTER_FLUENCY) + }) + .width('calc(100% - 32vp)') + .margin({ + top: 12, + left: 16, + right: 16 + }) + } + .width(300) + .height('100%') + .alignItems(HorizontalAlign.Start) + .backgroundColor('#2c2c2c') + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + } + + @Builder + private PreferenceDescriptionColumn( + title: Resource, + desc: Resource + ) { + Column() { + Text(title) + .fontColor('#F0F1F5') + .fontSize(16) + .fontWeight(FontWeight.Bold) + Text(desc) + .fontColor('#99F0F1F5') + .fontSize(12) + .margin({ + top: 4 + }) + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .padding({ + top: 12, + bottom: 12, + left: 20, + right: 20 + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreResolutionRatioButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreResolutionRatioButton.ets new file mode 100644 index 0000000..832bf43 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreResolutionRatioButton.ets @@ -0,0 +1,55 @@ +import { PLVLinkMicPushResolutionRatio, PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { lateInit, MutableObserver, toRaw } from '@polyvharmony/media-player-sdk'; + +@Component +export struct PLVSAMoreResolutionRatioButton { + iconPadding: number = 8 + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private ratio: PLVLinkMicPushResolutionRatio = PLVLinkMicPushResolutionRatio.RATIO_16_9 + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.streamerManager.pushResolutionRatio.observe((ratio) => this.ratio = ratio) + .pushTo(this.observers) + } + + build() { + Column() { + Image(this.ratioIcon()) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_push_resolution_ratio')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.sdk.streamerManager.setPushResolutionRatio(this.nextResolutionRatio()) + }) + } + + private ratioIcon(): Resource { + switch (toRaw(this.ratio)) { + case PLVLinkMicPushResolutionRatio.RATIO_16_9: + default: + return $r('app.media.plvsa_more_push_resolution_ratio_16_9') + case PLVLinkMicPushResolutionRatio.RATIO_4_3: + return $r('app.media.plvsa_more_push_resolution_ratio_4_3') + } + } + + private nextResolutionRatio(): PLVLinkMicPushResolutionRatio { + if (toRaw(this.ratio) === PLVLinkMicPushResolutionRatio.RATIO_16_9) { + return PLVLinkMicPushResolutionRatio.RATIO_4_3 + } else { + return PLVLinkMicPushResolutionRatio.RATIO_16_9 + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareButton.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareButton.ets new file mode 100644 index 0000000..b1fe2b6 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareButton.ets @@ -0,0 +1,32 @@ +import { PLVSAMoreShareLayout } from './PLVSAMoreShareLayout' + +@Component +export struct PLVSAMoreShareButton { + iconPadding: number = 8 + onClicked: (origin: () => void) => void = (origin) => { + origin() + } + private readonly controller = new CustomDialogController({ + builder: PLVSAMoreShareLayout(), + customStyle: true + }) + + build() { + Column() { + Image($r('app.media.plvsa_more_share_icon')) + .width(48) + .height(48) + .padding(this.iconPadding) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_more_share_title')) + .fontColor("#FFFFFF") + .fontSize(12) + .textAlign(TextAlign.Center) + } + .onClick(() => { + this.onClicked(() => { + this.controller.open() + }) + }) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareLayout.ets b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareLayout.ets new file mode 100644 index 0000000..3a4432d --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/more/widgets/PLVSAMoreShareLayout.ets @@ -0,0 +1,440 @@ +import { + PLVCommonConstants, + PLVLiveSceneSDK, + PLVLogger, + PLVSimpleWeb, + PLVWebController, + PLVToastUtils, + PLVUtils +} from '@polyvharmony/live-scenes-sdk'; +import { lateInit, runCatching } from '@polyvharmony/media-player-sdk'; +import { photoAccessHelper } from '@kit.MediaLibraryKit'; +import { image } from '@kit.ImageKit'; +import fs from '@ohos.file.fs' +import { display } from '@kit.ArkUI'; + +const TAG = 'PLVSAMoreShareLayout' + +@CustomDialog +export struct PLVSAMoreShareLayout { + controller: CustomDialogController = lateInit() + + build() { + if (this.isPortrait()) { + PLVSAMoreShareLayoutPort({ + controller: this.controller + }) + } else { + PLVSAMoreShareLayoutLand({ + controller: this.controller + }) + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +// + +@Component +struct PLVSAMoreShareLayoutPort { + controller: CustomDialogController = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly webController = new PLVWebController() + @State private posterUrl: string = "" + private saveImageController: CustomDialogController | undefined = undefined + private readonly plvsa_more_share_poster_web = 'plvsa_more_share_poster_web' + + async aboutToAppear(): Promise { + const posterUrl = await runCatching(this.sdk.interactManager.invitePoster.getInvitePosterUrl()) + if (posterUrl.success === true) { + this.posterUrl = posterUrl.data + this.webController.loadUrlCatch(this.posterUrl) + } else { + PLVLogger.error(TAG, `load invite poster fail: ${posterUrl.error.message}`) + } + } + + build() { + RelativeContainer() { + Stack() { + Stack() { + PLVSimpleWeb({ + controller: this.webController, + src: this.posterUrl + }) + .id(this.plvsa_more_share_poster_web) + } + .aspectRatio(9 / 16) + .borderRadius(8) + .clip(true) + } + .id('plvsa_more_share_poster_container') + .width('100%') + .margin({ + top: 4, + bottom: 24 + }) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + bottom: { anchor: 'plvsa_more_share_action_layout', align: VerticalAlign.Top } + }) + + Column() { + Grid() { + GridItem() { + ShareActionButton({ + image: $r('app.media.plvsa_more_share_action_save_image_icon'), + name: $r('app.string.plvsa_more_share_action_save_image') + }) + .onClick(() => this.onClickSaveImage()) + } + + GridItem() { + ShareActionButton({ + image: $r('app.media.plvsa_more_share_action_copy_link_icon'), + name: $r('app.string.plvsa_more_share_action_copy_link') + }) + .onClick(() => this.onClickCopyLink()) + } + } + .layoutWeight(1) + .columnsTemplate('1fr 1fr') + + Button($r('app.string.plvsa_more_share_action_cancel')) + .width(240) + .height(40) + .margin({ + top: 18 + }) + .fontColor('#ffffff') + .fontSize(14) + .backgroundColor('#19ffffff') + .borderRadius(30) + .onClick(() => { + this.controller.close() + }) + } + .id('plvsa_more_share_action_layout') + .width('100%') + .height(200) + .padding({ + left: 25, + right: 25, + top: 28, + bottom: 28 + }) + .backgroundColor('#2C2C2C') + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + .alignRules({ + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + } + .width('100%') + .height('100%') + .backgroundColor('#80464646') + } + + private async onClickSaveImage() { + const pixelMapResult = await runCatching(this.getUIContext() + .getComponentSnapshot() + .get(this.plvsa_more_share_poster_web)) + if (pixelMapResult.success === false) { + PLVLogger.error(TAG, `saveImage failed: ${pixelMapResult.error.message}`) + PLVToastUtils.shortShow($r('app.string.plvsa_more_share_action_save_image_fail_toast')) + return + } + this.saveImageController = new CustomDialogController({ + builder: SaveImageDialogPort({ + pixelMap: pixelMapResult.data + }), + customStyle: true + }) + this.saveImageController.open() + } + + private async onClickCopyLink() { + const watchUrlResult = await runCatching(this.sdk.interactManager.invitePoster.getLiveWatchUrl()) + if (watchUrlResult.success === true) { + const watchUrl = watchUrlResult.data + await PLVUtils.copyText(watchUrl) + PLVToastUtils.shortShow($r('app.string.plvsa_chat_copy_success')) + } + } +} + +@CustomDialog +struct SaveImageDialogPort { + controller?: CustomDialogController = lateInit() + pixelMap: PixelMap = lateInit() + + build() { + Column() { + Image(this.pixelMap) + .margin({ + bottom: 20 + }) + .aspectRatio(9 / 16) + .objectFit(ImageFit.Contain) + + SaveButton({ + icon: SaveIconStyle.FULL_FILLED, + text: SaveDescription.SAVE_IMAGE + }) + .onClick(async () => { + const result = await runCatching(this.saveImage()) + if (result.success === true) { + PLVToastUtils.shortShow($r('app.string.plvsa_more_share_action_save_image_success_toast')) + this.controller?.close() + } else { + PLVLogger.error(TAG, `saveImage failed: ${result.error.message}`) + PLVToastUtils.shortShow($r('app.string.plvsa_more_share_action_save_image_fail_toast')) + } + }) + } + .width(260) + .backgroundColor('#2C2C2C') + .borderRadius(16) + .padding({ + left: 24, + right: 24, + top: 20, + bottom: 18 + }) + } + + private async saveImage() { + const photoAccess = photoAccessHelper.getPhotoAccessHelper(getContext(this)) + const uri = await photoAccess.createAsset(photoAccessHelper.PhotoType.IMAGE, "png") + const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + const packer = image.createImagePacker() + await packer.packToFile(this.pixelMap, file.fd, { + format: "image/png", + quality: 100 + }) + await packer.release() + await fs.close(file) + } +} + +// + +// + +@Component +struct PLVSAMoreShareLayoutLand { + controller: CustomDialogController = lateInit() + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private readonly webController = new PLVWebController() + @State private posterUrl: string = "" + private saveImageController: CustomDialogController | undefined = undefined + private readonly plvsa_more_share_poster_web = 'plvsa_more_share_poster_web' + private readonly posterHeight = px2vp(display.getDefaultDisplaySync().height) - 32 + private readonly posterWidth = this.posterHeight / 16 * 9 + + async aboutToAppear(): Promise { + const posterUrl = await runCatching(this.sdk.interactManager.invitePoster.getInvitePosterUrl()) + if (posterUrl.success === true) { + this.posterUrl = posterUrl.data + this.webController.loadUrlCatch(this.posterUrl) + } else { + PLVLogger.error(TAG, `load invite poster fail: ${posterUrl.error.message}`) + } + } + + build() { + RelativeContainer() { + Stack() { + Stack() { + PLVSimpleWeb({ + controller: this.webController, + src: this.posterUrl + }) + .id(this.plvsa_more_share_poster_web) + .width(this.posterWidth) + .height(this.posterHeight) + } + .width(this.posterWidth) + .height(this.posterHeight) + .borderRadius(8) + .clip(true) + } + .id('plvsa_more_share_poster_container') + .margin({ + top: 16, + bottom: 16 + }) + .alignRules({ + center: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Center }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + right: { anchor: 'plvsa_more_share_action_layout', align: HorizontalAlign.Start }, + }) + + Column() { + Grid() { + GridItem() { + ShareActionButton({ + image: $r('app.media.plvsa_more_share_action_save_image_icon'), + name: $r('app.string.plvsa_more_share_action_save_image') + }) + .onClick(() => this.onClickSaveImage()) + } + + GridItem() { + ShareActionButton({ + image: $r('app.media.plvsa_more_share_action_copy_link_icon'), + name: $r('app.string.plvsa_more_share_action_copy_link') + }) + .onClick(() => this.onClickCopyLink()) + } + } + .layoutWeight(1) + .columnsTemplate('1fr 1fr') + + Button($r('app.string.plvsa_more_share_action_cancel')) + .width(240) + .height(40) + .margin({ + top: 18 + }) + .fontColor('#ffffff') + .fontSize(14) + .backgroundColor('#19ffffff') + .borderRadius(30) + .onClick(() => { + this.controller.close() + }) + } + .id('plvsa_more_share_action_layout') + .width(320) + .height('100%') + .padding({ + left: 25, + right: 25, + top: 28, + bottom: 28 + }) + .backgroundColor('#2C2C2C') + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + .alignRules({ + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End } + }) + } + .width('100%') + .height('100%') + .backgroundColor('#80464646') + } + + private async onClickSaveImage() { + const pixelMapResult = await runCatching(this.getUIContext() + .getComponentSnapshot() + .get(this.plvsa_more_share_poster_web)) + if (pixelMapResult.success === false) { + PLVLogger.error(TAG, `saveImage failed: ${pixelMapResult.error.message}`) + PLVToastUtils.shortShow($r('app.string.plvsa_more_share_action_save_image_fail_toast')) + return + } + this.saveImageController = new CustomDialogController({ + builder: SaveImageDialogLand({ + pixelMap: pixelMapResult.data + }), + customStyle: true + }) + this.saveImageController.open() + } + + private async onClickCopyLink() { + const watchUrlResult = await runCatching(this.sdk.interactManager.invitePoster.getLiveWatchUrl()) + if (watchUrlResult.success === true) { + const watchUrl = watchUrlResult.data + await PLVUtils.copyText(watchUrl) + PLVToastUtils.shortShow($r('app.string.plvsa_chat_copy_success')) + } + } +} + +@CustomDialog +struct SaveImageDialogLand { + controller?: CustomDialogController = lateInit() + pixelMap: PixelMap = lateInit() + + build() { + Column() { + Stack() { + Image(this.pixelMap) + .aspectRatio(9 / 16) + .objectFit(ImageFit.Contain) + } + .layoutWeight(1) + .margin({ + bottom: 20 + }) + + SaveButton({ + icon: SaveIconStyle.FULL_FILLED, + text: SaveDescription.SAVE_IMAGE + }) + .onClick(async () => { + const result = await runCatching(this.saveImage()) + if (result.success === true) { + PLVToastUtils.shortShow($r('app.string.plvsa_more_share_action_save_image_success_toast')) + this.controller?.close() + } else { + PLVLogger.error(TAG, `saveImage failed: ${result.error.message}`) + PLVToastUtils.shortShow($r('app.string.plvsa_more_share_action_save_image_fail_toast')) + } + }) + } + .height(px2vp(display.getDefaultDisplaySync().height) - 48) + .backgroundColor('#2C2C2C') + .borderRadius(16) + .padding({ + left: 24, + right: 24, + top: 20, + bottom: 18 + }) + } + + private async saveImage() { + const photoAccess = photoAccessHelper.getPhotoAccessHelper(getContext(this)) + const uri = await photoAccess.createAsset(photoAccessHelper.PhotoType.IMAGE, "png") + const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + const packer = image.createImagePacker() + await packer.packToFile(this.pixelMap, file.fd, { + format: "image/png", + quality: 100 + }) + await packer.release() + await fs.close(file) + } +} + +// + +@Component +struct ShareActionButton { + image: Resource = lateInit() + name: Resource = lateInit() + + build() { + Column() { + Image(this.image) + .width(52) + .height(52) + .padding(2) + Text(this.name) + .fontColor('#99F0F1F5') + .fontSize(12) + } + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/PLVSAStatusBarLayout.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/PLVSAStatusBarLayout.ets new file mode 100644 index 0000000..c001bbe --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/PLVSAStatusBarLayout.ets @@ -0,0 +1,236 @@ +import { PLVCommonConstants, PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { lateInit } from '@polyvharmony/media-player-sdk'; +import { PLVSAStatusChannelInfoBar } from './widgets/PLVSAStatusChannelInfoBar'; +import { PLVSAStatusMemberCountBar } from './widgets/PLVSAStatusMemberCountBar'; +import { PLVSAStatusNetworkBar } from './widgets/PLVSAStatusNetworkBar'; +import { PLVSAStatusNotificationBar } from './widgets/PLVSAStatusNotificationBar'; +import { PLVSAStatusStreamDurationBar } from './widgets/PLVSAStatusStreamDurationBar'; +import { PLVSAStatusUserInfoBar } from './widgets/PLVSAStatusUserInfoBar'; +import { display } from '@kit.ArkUI'; +import { PLVSAConfirmDialog } from '../../common/widget/PLVSAConfirmDialog'; +import { PLVSAPageDataBus } from '../../common/PLVSAPageDataBus'; +import { PLVSAStatusPushDowngradeNotifyBar } from './widgets/PLVSAStatusPushDowngradeNotifyBar'; + +@Component +export struct PLVSAStatusBarLayout { + build() { + if (this.isPortrait()) { + PLVSAStatusBarLayoutPort() + } else { + PLVSAStatusBarLayoutLand() + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSAStatusBarLayoutPort { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly finishStreamDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + hasTitle: false, + content: $r('app.string.plvsa_finish_stream_confirm_dialog_content'), + onClickConfirm: (controller) => { + this.pageDataBus.finishStream(this.sdk) + controller?.close() + } + }), + customStyle: true + }) + + build() { + RelativeContainer() { + PLVSAStatusChannelInfoBar() + .id('plvsa_status_bar_channel_info_bar') + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + + PLVSAStatusMemberCountBar() + .id('plvsa_status_bar_member_count_bar') + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: 'plvsa_status_bar_channel_info_bar', align: HorizontalAlign.End } + }) + .margin({ + left: 8 + }) + + PLVSAStatusStreamDurationBar() + .id('plvsa_status_bar_stream_duration_bar') + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: 'plvsa_status_bar_member_count_bar', align: HorizontalAlign.End } + }) + .margin({ + left: 8 + }) + + Image($r('app.media.plvsa_status_bar_close')) + .id('plvsa_status_bar_finish_stream_icon') + .width(32) + .height(32) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End } + }) + .onClick(() => { + this.finishStreamDialogController.open() + }) + + PLVSAStatusUserInfoBar() + .id('plvsa_status_bar_user_info_bar') + .alignRules({ + top: { anchor: 'plvsa_status_bar_channel_info_bar', align: VerticalAlign.Bottom }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + .margin({ + top: 8 + }) + + PLVSAStatusNetworkBar() + .id('plvsa_status_bar_network_bar') + .alignRules({ + top: { anchor: 'plvsa_status_bar_finish_stream_icon', align: VerticalAlign.Bottom }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End } + }) + .margin({ + top: 12 + }) + + PLVSAStatusNotificationBar() + .id('plvsa_status_bar_notification_bar') + .alignRules({ + top: { anchor: 'plvsa_status_bar_user_info_bar', align: VerticalAlign.Bottom }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + .margin({ + top: 16 + }) + + PLVSAStatusPushDowngradeNotifyBar() + .id('plvsa_status_bar_push_downgrade_notify') + .alignRules({ + top: { anchor: 'plvsa_status_bar_notification_bar', align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 8 + }) + + } + .width('100%') + .height('100%') + .padding(8) + } +} + +@Component +struct PLVSAStatusBarLayoutLand { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly finishStreamDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + hasTitle: false, + content: $r('app.string.plvsa_finish_stream_confirm_dialog_content'), + onClickConfirm: (controller) => { + this.pageDataBus.finishStream(this.sdk) + controller?.close() + } + }), + customStyle: true + }) + + build() { + RelativeContainer() { + PLVSAStatusChannelInfoBar() + .id('plvsa_status_bar_channel_info_bar') + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + + PLVSAStatusMemberCountBar() + .id('plvsa_status_bar_member_count_bar') + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: 'plvsa_status_bar_channel_info_bar', align: HorizontalAlign.End } + }) + .margin({ + left: 8 + }) + + PLVSAStatusStreamDurationBar() + .id('plvsa_status_bar_stream_duration_bar') + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: 'plvsa_status_bar_member_count_bar', align: HorizontalAlign.End } + }) + .margin({ + left: 8 + }) + + Image($r('app.media.plvsa_status_bar_close')) + .id('plvsa_status_bar_finish_stream_icon') + .width(32) + .height(32) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End } + }) + .onClick(() => { + this.finishStreamDialogController.open() + }) + + PLVSAStatusUserInfoBar() + .id('plvsa_status_bar_user_info_bar') + .alignRules({ + top: { anchor: 'plvsa_status_bar_channel_info_bar', align: VerticalAlign.Bottom }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + .margin({ + top: 8 + }) + + PLVSAStatusNetworkBar() + .id('plvsa_status_bar_network_bar') + .alignRules({ + center: { anchor: 'plvsa_status_bar_finish_stream_icon', align: VerticalAlign.Center }, + right: { anchor: 'plvsa_status_bar_finish_stream_icon', align: HorizontalAlign.Start } + }) + .margin({ + right: 8 + }) + + PLVSAStatusNotificationBar() + .id('plvsa_status_bar_notification_bar') + .alignRules({ + top: { anchor: 'plvsa_status_bar_user_info_bar', align: VerticalAlign.Bottom }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + .margin({ + top: 16 + }) + + PLVSAStatusPushDowngradeNotifyBar() + .id('plvsa_status_bar_push_downgrade_notify') + .alignRules({ + top: { anchor: 'plvsa_status_bar_notification_bar', align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 8 + }) + + } + .width('100%') + .height('100%') + .padding(8) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoBar.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoBar.ets new file mode 100644 index 0000000..53a9ae0 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoBar.ets @@ -0,0 +1,41 @@ +import { PLVSAStatusChannelInfoLayout } from './PLVSAStatusChannelInfoLayout' + +@Component +export struct PLVSAStatusChannelInfoBar { + private readonly channelInfoLayoutController = new CustomDialogController({ + builder: PLVSAStatusChannelInfoLayout(), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + build() { + Row() { + Image($r('app.media.plvsa_status_bar_channel_info_icon')) + .width(20) + .height(20) + .objectFit(ImageFit.Contain) + Text($r('app.string.plvsa_status_bar_channel_info')) + .fontColor('#FFFFFF') + .fontSize(14) + .margin({ + left: 4, + right: 2 + }) + Image($r('app.media.plvsa_status_bar_channel_info_nav_icon')) + .width(16) + .height(16) + .objectFit(ImageFit.Contain) + } + .backgroundColor('#33000000') + .borderRadius(18) + .padding({ + left: 10, + right: 10, + top: 8, + bottom: 8 + }) + .onClick(() => { + this.channelInfoLayoutController.open() + }) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoLayout.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoLayout.ets new file mode 100644 index 0000000..714e9da --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusChannelInfoLayout.ets @@ -0,0 +1,237 @@ +import { PLVCommonConstants, PLVLiveSceneSDK, PLVToastUtils, PLVUtils } from '@polyvharmony/live-scenes-sdk'; +import { isTextBlank, lateInit } from '@polyvharmony/media-player-sdk'; +import { display } from '@kit.ArkUI'; + +@CustomDialog +export struct PLVSAStatusChannelInfoLayout { + controller: CustomDialogController = lateInit() + + build() { + if (this.isPortrait()) { + PLVSAStatusChannelInfoLayoutPort() + } else { + PLVSAStatusChannelInfoLayoutLand() + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSAStatusChannelInfoLayoutPort { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private liveTitle: string = "" + @State private startTime: string | Resource = $r('app.string.plvsa_status_bar_channel_info_start_time_not_set') + @State private channelId: string = "" + + aboutToAppear(): void { + this.liveTitle = this.sdk.channelData.streamerData?.channelName ?? "" + const startTime = this.sdk.channelData.liveDetail?.startTime?.toString?.() ?? "" + if (!isTextBlank(startTime)) { + this.startTime = startTime + } + this.channelId = this.sdk.channelData.loginChannelId?.toString() ?? "" + } + + build() { + Column() { + Text($r('app.string.plvsa_status_bar_channel_info')) + .fontColor('#F0F1F5') + .fontSize(18) + + Row() { + Text($r('app.string.plvsa_status_bar_channel_info_live_title')) + .fontColor('#99F0F1F5') + .fontSize(14) + Text(this.liveTitle) + .fontColor('#F0F1F5') + .fontSize(14) + .layoutWeight(1) + } + .width('100%') + .alignItems(VerticalAlign.Top) + .margin({ + top: 22 + }) + + Row() { + Text($r('app.string.plvsa_status_bar_channel_info_start_time')) + .fontColor('#99F0F1F5') + .fontSize(14) + Text(this.startTime) + .fontColor('#F0F1F5') + .fontSize(14) + } + .margin({ + top: 12 + }) + + Row() { + Text($r('app.string.plvsa_status_bar_channel_info_channel_id')) + .fontColor('#99F0F1F5') + .fontSize(14) + Text(this.channelId) + .fontColor('#F0F1F5') + .fontSize(14) + Text($r('app.string.plvsa_status_bar_channel_info_copy')) + .fontColor('#FFFFFF') + .fontSize(12) + .padding({ + left: 12, + right: 12, + top: 6, + bottom: 6 + }) + .margin({ + left: 12 + }) + .borderRadius(16) + .linearGradient({ + angle: 90, + colors: [ + ['#0080FF', 0], + ['#3399FF', 1] + ] + }) + .onClick(async () => { + await PLVUtils.copyText(this.channelId); + PLVToastUtils.shortShow($r('app.string.plvsa_status_bar_channel_info_copy_success')) + }) + } + .margin({ + top: 12 + }) + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .borderRadius({ + topLeft: 16, + topRight: 16 + }) + .backgroundColor('#2c2c2c') + .padding(32) + } +} + +@Component +struct PLVSAStatusChannelInfoLayoutLand { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private liveTitle: string = "" + @State private startTime: string | Resource = $r('app.string.plvsa_status_bar_channel_info_start_time_not_set') + @State private channelId: string = "" + + aboutToAppear(): void { + this.liveTitle = this.sdk.channelData.streamerData?.channelName ?? "" + const startTime = this.sdk.channelData.liveDetail?.startTime?.toString?.() ?? "" + if (!isTextBlank(startTime)) { + this.startTime = startTime + } + this.channelId = this.sdk.channelData.loginChannelId?.toString() ?? "" + } + + build() { + RelativeContainer() { + Text($r('app.string.plvsa_status_bar_channel_info')) + .id('plvsa_status_bar_channel_info_title') + .fontColor('#F0F1F5') + .fontSize(18) + + Scroll() { + Column() { + Text($r('app.string.plvsa_status_bar_channel_info_live_title')) + .fontColor('#99F0F1F5') + .fontSize(14) + .margin({ + top: 6 + }) + + Text(this.liveTitle) + .fontColor('#F0F1F5') + .fontSize(14) + .margin({ + top: 6 + }) + + Text($r('app.string.plvsa_status_bar_channel_info_start_time')) + .fontColor('#99F0F1F5') + .fontSize(14) + .margin({ + top: 12 + }) + + Text(this.startTime) + .fontColor('#F0F1F5') + .fontSize(14) + .margin({ + top: 6 + }) + + Text($r('app.string.plvsa_status_bar_channel_info_channel_id')) + .fontColor('#99F0F1F5') + .fontSize(14) + .margin({ + top: 12 + }) + + Row() { + Text(this.channelId) + .fontColor('#F0F1F5') + .fontSize(14) + Text($r('app.string.plvsa_status_bar_channel_info_copy')) + .fontColor('#FFFFFF') + .fontSize(12) + .padding({ + left: 12, + right: 12, + top: 6, + bottom: 6 + }) + .margin({ + left: 12 + }) + .borderRadius(16) + .linearGradient({ + angle: 90, + colors: [ + ['#0080FF', 0], + ['#3399FF', 1] + ] + }) + .onClick(async () => { + await PLVUtils.copyText(this.channelId); + PLVToastUtils.shortShow($r('app.string.plvsa_status_bar_channel_info_copy_success')) + }) + } + .margin({ + top: 6 + }) + + Blank().height(16) + } + .width('100%') + .alignItems(HorizontalAlign.Start) + } + .id('plvsa_status_bar_channel_info_container') + .width('100%') + .align(Alignment.Top) + .alignRules({ + top: { anchor: 'plvsa_status_bar_channel_info_title', align: VerticalAlign.Bottom }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .margin({ + top: 16 + }) + } + .width(300) + .height('100%') + .borderRadius({ + topLeft: 16, + bottomLeft: 16 + }) + .backgroundColor('#2c2c2c') + .padding(32) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusMemberCountBar.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusMemberCountBar.ets new file mode 100644 index 0000000..656c310 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusMemberCountBar.ets @@ -0,0 +1,166 @@ +import { PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk' +import { lateInit, MutableObserver, seconds } from '@polyvharmony/media-player-sdk' +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus' +import { PLVSAMemberLayout } from '../../member/PLVSAMemberLayout' + +@Component +export struct PLVSAStatusMemberCountBar { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private memberCount: number = 0 + private readonly memberLayoutController = new CustomDialogController({ + builder: PLVSAMemberLayout(), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + @State private isViewerRequestRedPointVisible: boolean = false + @State private isViewerRequestNotifyBarVisible: boolean = false + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.memberManager.channelViewerCount.observe(it => this.memberCount = it) + .pushTo(this.observers) + this.sdk.memberManager.onViewerRequestLinkMic.observe(() => { + const memberLayoutVisible = this.pageDataBus.memberLayoutVisible.value ?? false + if (!memberLayoutVisible) { + this.isViewerRequestRedPointVisible = true + this.isViewerRequestNotifyBarVisible = true + } + }) + .pushTo(this.observers) + this.pageDataBus.memberLayoutVisible.observe((memberLayoutVisible) => { + if (memberLayoutVisible) { + this.isViewerRequestRedPointVisible = false + this.isViewerRequestNotifyBarVisible = false + } + }).pushTo(this.observers) + } + + build() { + Row() { + Image($r('app.media.plvsa_status_bar_member_count_icon')) + .width(20) + .height(20) + .objectFit(ImageFit.Contain) + Row() { + Text(this.memberCount.toString()) + .fontColor('#FFFFFF') + .fontSize(14) + .fontWeight(FontWeight.Bold) + Circle() + .id('plvsa_member_button_new_viewer_request_red_point') + .width(6) + .height(6) + .fill('#FF3B30') + .visibility(this.isViewerRequestRedPointVisible ? Visibility.Visible : Visibility.Hidden) + .margin({ + left: -2 + }) + } + .alignItems(VerticalAlign.Top) + .margin({ + left: 4 + }) + } + .backgroundColor('#33000000') + .borderRadius(18) + .padding({ + left: 10, + right: 10, + top: 8, + bottom: 8 + }) + .bindPopup(this.isViewerRequestNotifyBarVisible, { + builder: () => { + this.linkmicNewRequestNotifyBarPopup() + }, + placement: Placement.Bottom, + popupColor: '#66000000', + backgroundBlurStyle: BlurStyle.NONE, + radius: 20, + onStateChange: (e) => { + this.isViewerRequestNotifyBarVisible = e.isVisible + } + }) + .onClick(() => { + this.memberLayoutController.open() + }) + } + + @Builder + private linkmicNewRequestNotifyBarPopup() { + PLVSALinkMicNewRequestNotifyBar({ + onHide: () => { + this.isViewerRequestNotifyBarVisible = false + }, + onOpenMemberLayout: () => { + this.memberLayoutController.open() + } + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSALinkMicNewRequestNotifyBar { + onHide: () => void = lateInit() + onOpenMemberLayout: () => void = lateInit() + autoHideTimeoutId: number | undefined = undefined + + aboutToAppear(): void { + this.autoHideTimeoutId = setTimeout(() => { + this.onHide() + }, seconds(10).toMillis()) + } + + build() { + Row() { + Image($r('app.media.plvsa_linkmic_new_request_icon')) + .width(18) + .height(18) + Text($r('app.string.plvsa_linkmic_new_request_hint_text')) + .fontSize(14) + .fontColor('#F0F1F5') + .margin({ + left: 5 + }) + Text($r('app.string.plvsa_linkmic_new_request_check_text')) + .width(50) + .height(24) + .textAlign(TextAlign.Center) + .fontSize(12) + .fontColor('#FFFFFF') + .borderRadius(16) + .linearGradient({ + angle: 0, + colors: [ + ['#0080FF', 0], + ['#3399FF', 1] + ] + }) + .margin({ + left: 12 + }) + .onClick(() => { + this.onOpenMemberLayout() + }) + } + .onClick(() => { + this.onHide() + }) + .padding({ + top: 4, + bottom: 4, + right: 5, + left: 12 + }) + } + + aboutToDisappear(): void { + clearTimeout(this.autoHideTimeoutId) + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNetworkBar.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNetworkBar.ets new file mode 100644 index 0000000..23b4bd8 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNetworkBar.ets @@ -0,0 +1,116 @@ +import { PLVLiveSceneSDK, PLVNetworkQuality, PLVNetworkStatistics } from '@polyvharmony/live-scenes-sdk' +import { lateInit, MutableObserver } from '@polyvharmony/media-player-sdk' + +@Component +export struct PLVSAStatusNetworkBar { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private networkQuality: PLVNetworkQuality = PLVNetworkQuality.UNKNOWN + @State private networkStatistics: PLVNetworkStatistics | undefined = undefined + @State private networkStatisticsPopupVisible: boolean = false + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.linkmicNetworkQuality.observe(it => this.networkQuality = it) + .pushTo(this.observers) + this.sdk.linkmicManager.linkmicNetworkStatistics.observe(it => this.networkStatistics = it) + .pushTo(this.observers) + } + + build() { + Row() { + Image(this.networkQualityIcon()) + .width(12) + .height(12) + + Text(this.networkQualityText()) + .fontColor('#F0F1F5') + .fontSize(12) + .margin({ + left: 4 + }) + } + .backgroundColor('#33000000') + .borderRadius(10) + .padding({ + left: 8, + right: 8, + top: 2, + bottom: 2 + }) + .onClick(() => { + if (this.networkStatistics !== undefined) { + this.networkStatisticsPopupVisible = true + } + }) + .bindPopup(this.networkStatisticsPopupVisible, { + builder: this.networkStatisticsPopup, + placement: Placement.Bottom, + backgroundBlurStyle: BlurStyle.NONE, + popupColor: '#212121', + radius: 16, + onStateChange: (event) => { + this.networkStatisticsPopupVisible = event.isVisible + } + }) + } + + private networkQualityIcon(): Resource { + switch (this.networkQuality) { + case PLVNetworkQuality.EXCELLENT: + case PLVNetworkQuality.GOOD: + return $r('app.media.plvsa_status_bar_network_quality_good_icon') + case PLVNetworkQuality.POOR: + case PLVNetworkQuality.BAD: + return $r('app.media.plvsa_status_bar_network_quality_moderate_icon') + case PLVNetworkQuality.VERY_BAD: + case PLVNetworkQuality.DISCONNECT: + case PLVNetworkQuality.UNKNOWN: + default: + return $r('app.media.plvsa_status_bar_network_quality_bad_icon') + } + } + + private networkQualityText(): Resource { + switch (this.networkQuality) { + case PLVNetworkQuality.EXCELLENT: + return $r('app.string.plvsa_status_bar_network_quality_excellent') + case PLVNetworkQuality.GOOD: + return $r('app.string.plvsa_status_bar_network_quality_good') + case PLVNetworkQuality.POOR: + return $r('app.string.plvsa_status_bar_network_quality_poor') + case PLVNetworkQuality.BAD: + return $r('app.string.plvsa_status_bar_network_quality_bad') + case PLVNetworkQuality.VERY_BAD: + return $r('app.string.plvsa_status_bar_network_quality_very_bad') + case PLVNetworkQuality.DISCONNECT: + return $r('app.string.plvsa_status_bar_network_quality_disconnect') + case PLVNetworkQuality.UNKNOWN: + default: + return $r('app.string.plvsa_status_bar_network_quality_unknown') + } + } + + @Builder + private networkStatisticsPopup() { + if (this.networkStatistics !== undefined) { + Column() { + Text($r('app.string.plvsa_status_bar_network_delay_text', this.networkStatistics.upDelayMs.toString())) + .fontColor('#F0F1F5') + .fontSize(14) + Text($r('app.string.plvsa_status_bar_network_loss_rate_text', this.networkStatistics.upLossRate.toFixed(1), this.networkStatistics.downLossRate.toFixed(1))) + .fontColor('#F0F1F5') + .fontSize(14) + .margin({ + top: 6 + }) + } + .alignItems(HorizontalAlign.Start) + .padding(12) + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNotificationBar.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNotificationBar.ets new file mode 100644 index 0000000..4c1c75a --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusNotificationBar.ets @@ -0,0 +1,73 @@ +import { PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk'; +import { DerivedState, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; + +@Component +export struct PLVSAStatusNotificationBar { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private isCameraEnable: boolean = false + @State private isMicrophoneEnable: boolean = false + @State private isVisible: boolean = false + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + const localVideoEnable = new DerivedState(() => { + return this.sdk.linkmicManager.localLinkMicViewer.value?.isVideoEnable?.value ?? false + }) + const localAudioEnable = new DerivedState(() => { + return this.sdk.linkmicManager.localLinkMicViewer.value?.isAudioEnable?.value ?? false + }) + const visible = new DerivedState(() => { + return !(localVideoEnable.value ?? false) || !(localAudioEnable.value ?? false) + }) + localVideoEnable.observe(it => this.isCameraEnable = it).pushTo(this.observers) + localAudioEnable.observe(it => this.isMicrophoneEnable = it).pushTo(this.observers) + visible.observe(it => this.isVisible = it).pushTo(this.observers) + } + + build() { + Row() { + Text($r('app.string.plvsa_status_bar_notification')) + .width(50) + .height(24) + .textAlign(TextAlign.Center) + .fontColor('#FFFFFF') + .fontSize(12) + .linearGradient({ + angle: 90, + colors: [ + ['#0080FF', 0], + ['#3399FF', 1] + ] + }) + .borderRadius(16) + + Text(this.notificationContentText()) + .fontColor('#FFFFFF') + .fontSize(14) + .margin({ + left: 8 + }) + } + .visibility(this.isVisible ? Visibility.Visible : Visibility.None) + .backgroundColor('#33000000') + .borderRadius(18) + .padding(8) + } + + private notificationContentText(): string | Resource { + if (!this.isCameraEnable && !this.isMicrophoneEnable) { + return $r('app.string.plvsa_status_bar_notify_camera_microphone_disabled') + } else if (!this.isCameraEnable) { + return $r('app.string.plvsa_status_bar_notify_camera_disabled') + } else if (!this.isMicrophoneEnable) { + return $r('app.string.plvsa_status_bar_notify_microphone_disabled') + } else { + return "" + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusPushDowngradeNotifyBar.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusPushDowngradeNotifyBar.ets new file mode 100644 index 0000000..7ab29cc --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusPushDowngradeNotifyBar.ets @@ -0,0 +1,78 @@ +import { + PLVLiveSceneSDK, + PLVNetworkStatistics, + PLVPushDowngradePreference, + PLVToastUtils +} from "@polyvharmony/live-scenes-sdk"; +import { lateInit, minutes, MutableObserver, seconds } from "@polyvharmony/media-player-sdk"; + +@Component +export struct PLVSAStatusPushDowngradeNotifyBar { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private isVisible: boolean = false + private lastShowNotifyTimestamp = 0 + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.linkmicNetworkStatistics.observe(it => this.onNetworkStatistics(it)) + .pushTo(this.observers) + } + + build() { + if (this.isVisible) { + Row() { + Text($r('app.string.plvsa_push_downgrade_notify_text')) + .fontColor('#F0F1F5') + .fontSize(12) + .margin({ + left: 12 + }) + Text($r('app.string.plvsa_push_downgrade_notify_action')) + .fontColor('#FF6363') + .fontSize(12) + .padding(4) + .onClick(() => { + this.sdk.streamerManager.setPushDowngradePreference(PLVPushDowngradePreference.PREFER_BETTER_FLUENCY) + PLVToastUtils.shortShow($r('app.string.plvsa_push_downgrade_notify_switch_success')) + this.hide() + }) + Image($r("app.media.plvsa_status_bar_push_downgrade_notify_bar_close_icon")) + .width(24) + .height(24) + .padding(6) + .margin({ + left: 4, + right: 4 + }) + .onClick(() => this.hide()) + } + .backgroundColor('#991B202D') + .borderRadius(40) + } + } + + private onNetworkStatistics(networkStatistics: PLVNetworkStatistics) { + const isBadNetwork = networkStatistics.upLossRate > 30 + const canChangeToFluency = this.sdk.streamerManager.pushDowngradePreference.value === PLVPushDowngradePreference.PREFER_BETTER_QUALITY + if (isBadNetwork && canChangeToFluency && Date.now() - this.lastShowNotifyTimestamp > minutes(10).toMillis()) { + this.show() + } + } + + private show() { + this.lastShowNotifyTimestamp = Date.now() + this.isVisible = true + setTimeout(() => { + this.hide() + }, seconds(10).toMillis()) + } + + private hide() { + this.isVisible = false + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusStreamDurationBar.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusStreamDurationBar.ets new file mode 100644 index 0000000..a55c52f --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusStreamDurationBar.ets @@ -0,0 +1,67 @@ +import { PLVLiveSceneSDK, PLVScheduledTask, PLVStreamerState, PLVTimeUtils } from '@polyvharmony/live-scenes-sdk' +import { lateInit, MutableObserver, seconds } from '@polyvharmony/media-player-sdk' + +@Component +export struct PLVSAStatusStreamDurationBar { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private durationText: string = "00:00:00" + @State private isVisible: boolean = false + private updateDurationTask: PLVScheduledTask | undefined = undefined + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.updateDurationTask = new PLVScheduledTask( + () => { + this.updateDuration() + }, + 0, + seconds(1).toMillis() + ) + this.updateDurationTask.start() + this.sdk.streamerManager.streamerState.observe(streamerState => { + this.isVisible = streamerState === PLVStreamerState.START + }).pushTo(this.observers) + } + + build() { + Row() { + Circle() + .width(8) + .height(8) + .fill('#FF3B30') + Text(this.durationText) + .fontColor('#FFFFFF') + .fontSize(14) + .fontWeight(FontWeight.Bold) + .margin({ + left: 6 + }) + } + .backgroundColor('#33000000') + .borderRadius(18) + .padding({ + left: 10, + right: 10, + top: 10, + bottom: 10 + }) + .visibility(this.isVisible ? Visibility.Visible : Visibility.None) + } + + private updateDuration() { + const startTimestamp = this.sdk.streamerManager.liveStartTimestamp.value + const currentTimestamp = Date.now() + if (startTimestamp === undefined || currentTimestamp < startTimestamp) { + this.durationText = "00:00:00" + return + } + this.durationText = PLVTimeUtils.generateTime(currentTimestamp - startTimestamp, true) + } + + aboutToDisappear(): void { + this.updateDurationTask?.cancel() + this.updateDurationTask = undefined + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusUserInfoBar.ets b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusUserInfoBar.ets new file mode 100644 index 0000000..cd13576 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/statusbar/widgets/PLVSAStatusUserInfoBar.ets @@ -0,0 +1,78 @@ +import { PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk' +import { DerivedState, extendNumber, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk' + +@Component +export struct PLVSAStatusUserInfoBar { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @State private actorNickName: string = "" + @State private isAudioEnable: boolean = false + @State private audioVolume: number = 0 + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.initActorNickName() + const audioEnableState = new DerivedState(() => this.sdk.linkmicManager.localLinkMicViewer.value?.isAudioEnable.value ?? false) + audioEnableState.observe(it => this.isAudioEnable = it).pushTo(this.observers) + const audioVolumeState = new DerivedState(() => this.sdk.linkmicManager.localLinkMicViewer.value?.audioVolume.value ?? 0) + audioVolumeState.observe(it => this.audioVolume = it).pushTo(this.observers) + } + + private initActorNickName() { + const actor = this.sdk.channelData.viewerActor + const nickName = this.sdk.channelData.viewerName ?? "" + let actorNickName: string + if (actor !== undefined) { + actorNickName = `${actor}-${nickName}` + } else { + actorNickName = nickName + } + if (actorNickName.length > 20) { + this.actorNickName = actorNickName.substring(0, 20) + "..." + } else { + this.actorNickName = actorNickName + } + } + + build() { + Row() { + Text(this.actorNickName) + .fontColor('#FFFFFF') + .fontSize(12) + .maxLines(1) + .textOverflow({ + overflow: TextOverflow.Ellipsis + }) + .ellipsisMode(EllipsisMode.END) + + Image(this.audioVolumeIcon()) + .width(14) + .height(14) + .margin({ + left: 6 + }) + } + .backgroundColor('#33000000') + .borderRadius(10) + .padding({ + left: 8, + right: 8, + top: 2, + bottom: 2 + }) + } + + private audioVolumeIcon(): Resource { + if (!this.isAudioEnable) { + return $r('app.media.plvsa_linkmic_audio_volume_closed') + } else { + const clampValue = extendNumber(this.audioVolume).coerceIn_ext(0, 100) + const normalizeVolume = Math.round(clampValue / 10) * 10 + return $r(`app.media.plvsa_linkmic_audio_volume_value_${normalizeVolume}`) + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/toolbar/PLVSAToolBarLayout.ets b/scenes_streamerAlone/src/main/ets/components/toolbar/PLVSAToolBarLayout.ets new file mode 100644 index 0000000..72887b0 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/toolbar/PLVSAToolBarLayout.ets @@ -0,0 +1,32 @@ +import { PLVLiveSceneSDK } from '@polyvharmony/live-scenes-sdk' +import { lateInit } from '@polyvharmony/media-player-sdk' +import { PLVSAPageDataBus } from '../../common/PLVSAPageDataBus' +import { PLVSALinkMicButton } from '../linkmic/widgets/PLVSALinkMicButton' +import { PLVSAMoreLayout } from '../more/PLVSAMoreLayout' +import { PLVSAToolBarLinkMicLayoutButton } from './widgets/PLVSAToolBarLinkMicLayoutButton' + +@Component +export struct PLVSAToolBarLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly moreLayoutController = new CustomDialogController({ + builder: PLVSAMoreLayout(), + alignment: DialogAlignment.BottomEnd, + customStyle: true + }) + + build() { + Row({ space: 12 }) { + PLVSAToolBarLinkMicLayoutButton() + + PLVSALinkMicButton() + + Image($r("app.media.plvsa_tool_bar_more_button_icon")) + .width(36) + .height(36) + .onClick(() => { + this.moreLayoutController.open() + }) + } + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/components/toolbar/widgets/PLVSAToolBarLinkMicLayoutButton.ets b/scenes_streamerAlone/src/main/ets/components/toolbar/widgets/PLVSAToolBarLinkMicLayoutButton.ets new file mode 100644 index 0000000..0810683 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/components/toolbar/widgets/PLVSAToolBarLinkMicLayoutButton.ets @@ -0,0 +1,52 @@ +import { PLVLiveSceneSDK, PLVUserType } from '@polyvharmony/live-scenes-sdk' +import { lateInit, MutableObserver } from '@polyvharmony/media-player-sdk' +import { PLVSAPageDataBus } from '../../../common/PLVSAPageDataBus' +import { PLVSALinkMicLayoutType } from '../../linkmic/PLVSALinkMicLayout' + +@Component +export struct PLVSAToolBarLinkMicLayoutButton { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State private isVisible: boolean = false + @State private layoutType: PLVSALinkMicLayoutType = PLVSALinkMicLayoutType.TILE + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.channelLinkMicViewers.observe(linkmicViewers => { + const isTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + this.isVisible = isTeacher && linkmicViewers.length > 1 + }) + .pushTo(this.observers) + this.pageDataBus.linkmicLayoutType.observe(it => this.layoutType = it).pushTo(this.observers) + } + + build() { + if (this.isVisible) { + Image(this.layoutTypeIcon()) + .width(36) + .height(36) + .onClick(() => { + if (this.layoutType === PLVSALinkMicLayoutType.TILE) { + this.pageDataBus.linkmicLayoutType.setValue(PLVSALinkMicLayoutType.SPEAKER) + } else { + this.pageDataBus.linkmicLayoutType.setValue(PLVSALinkMicLayoutType.TILE) + } + }) + } + } + + private layoutTypeIcon(): Resource { + switch (this.layoutType) { + case PLVSALinkMicLayoutType.TILE: + default: + return $r('app.media.plvsa_linkmic_layout_speaker_icon'); + case PLVSALinkMicLayoutType.SPEAKER: + return $r('app.media.plvsa_linkmic_layout_tile_icon'); + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/layouts/end/PLVSALiveEndLayout.ets b/scenes_streamerAlone/src/main/ets/layouts/end/PLVSALiveEndLayout.ets new file mode 100644 index 0000000..9fe83ae --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/layouts/end/PLVSALiveEndLayout.ets @@ -0,0 +1,282 @@ +import { PLVCommonConstants, PLVLiveSceneSDK, PLVTimeUtils, PLVUserType } from '@polyvharmony/live-scenes-sdk'; +import { extendNumber, lateInit } from '@polyvharmony/media-player-sdk'; +import { display, router } from '@kit.ArkUI'; + +@Component +export struct PLVSALiveEndLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + + aboutToAppear(): void { + const isGuest = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_GUEST + if (isGuest) { + router.back() + } + } + + build() { + if (this.isPortrait()) { + PLVSALiveEndLayoutPort() + } else { + PLVSALiveEndLayoutLand() + } + } + + private isPortrait(): boolean { + const orientation = display.getDefaultDisplaySync().orientation + return orientation === display.Orientation.PORTRAIT || orientation === display.Orientation.PORTRAIT_INVERTED + } +} + +@Component +struct PLVSALiveEndLayoutPort { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private liveTimestampRange: string = "" + private liveTimeDuration: string = "" + + aboutToAppear(): void { + const start = new Date() + const current = new Date() + const liveStartTimestamp = this.sdk.streamerManager.liveStartTimestamp.value ?? current.getTime() + const liveEndTimestamp = current.getTime() + start.setTime(liveStartTimestamp) + + const pad = (num: number) => num.toString().padStart(2, '0') + const startTimeStr = `${pad(start.getHours())}:${pad(start.getMinutes())}:${pad(start.getSeconds())}` + const endTimeStr = `${pad(current.getHours())}:${pad(current.getMinutes())}:${pad(current.getSeconds())}` + this.liveTimestampRange = `${startTimeStr}~${endTimeStr}` + const liveDuration = extendNumber(liveEndTimestamp - liveStartTimestamp).coerceAtLeast_ext(0) + this.liveTimeDuration = PLVTimeUtils.generateTime(liveDuration, true) + } + + build() { + RelativeContainer() { + Image($r('app.media.plvsa_streamer_finish_icon')) + .id('plvsa_live_end_icon') + .width(100) + .height(84) + .objectFit(ImageFit.Contain) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 69 + }) + + Text($r('app.string.plvsa_live_end_text')) + .id('plvsa_live_end_text') + .fontSize(24) + .fontColor('#F0F1F5') + .alignRules({ + top: { anchor: 'plvsa_live_end_icon', align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 6 + }) + + Shape() + .id('plvsa_live_end_time_split') + .width(1) + .height(52) + .backgroundColor('#33FFFFFF') + .alignRules({ + top: { anchor: 'plvsa_live_end_text', align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 40 + }) + + Column() { + Text(this.liveTimestampRange) + .fontColor('#CCF0F1F5') + .fontSize(16) + .fontWeight(FontWeight.Bold) + Blank().height(10) + Text($r('app.string.plvsa_live_timestamp_text')) + .fontColor('#CCF0F1F5') + .fontSize(14) + } + .id('plvsa_live_end_timestamp_range') + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + right: { anchor: 'plvsa_live_end_time_split', align: HorizontalAlign.Start }, + center: { anchor: 'plvsa_live_end_time_split', align: VerticalAlign.Center } + }) + + Column() { + Text(this.liveTimeDuration) + .fontColor('#CCF0F1F5') + .fontSize(16) + .fontWeight(FontWeight.Bold) + Blank().height(10) + Text($r('app.string.plvsa_live_duration_text')) + .fontColor('#CCF0F1F5') + .fontSize(14) + } + .id('plvsa_live_end_duration_range') + .alignRules({ + left: { anchor: 'plvsa_live_end_time_split', align: HorizontalAlign.End }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End }, + center: { anchor: 'plvsa_live_end_time_split', align: VerticalAlign.Center } + }) + + Button($r('app.string.plvsa_confirm_dialog_confirm')) + .width(180) + .height(50) + .fontSize(16) + .fontColor('#FFFFFF') + .linearGradient({ + angle: 90, + colors: [ + ['#0080FF', 0], + ['#3399FF', 0] + ] + }) + .borderRadius(25) + .alignRules({ + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + bottom: 119 + }) + .onClick(() => { + router.back() + }) + } + .width('100%') + .height('100%') + .backgroundColor('#2c2c2c') + } +} + +@Component +struct PLVSALiveEndLayoutLand { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private liveTimestampRange: string = "" + private liveTimeDuration: string = "" + + aboutToAppear(): void { + const start = new Date() + const current = new Date() + const liveStartTimestamp = this.sdk.streamerManager.liveStartTimestamp.value ?? current.getTime() + const liveEndTimestamp = current.getTime() + start.setTime(liveStartTimestamp) + + const pad = (num: number) => num.toString().padStart(2, '0') + const startTimeStr = `${pad(start.getHours())}:${pad(start.getMinutes())}:${pad(start.getSeconds())}` + const endTimeStr = `${pad(current.getHours())}:${pad(current.getMinutes())}:${pad(current.getSeconds())}` + this.liveTimestampRange = `${startTimeStr}~${endTimeStr}` + const liveDuration = extendNumber(liveEndTimestamp - liveStartTimestamp).coerceAtLeast_ext(0) + this.liveTimeDuration = PLVTimeUtils.generateTime(liveDuration, true) + } + + build() { + RelativeContainer() { + Image($r('app.media.plvsa_streamer_finish_icon')) + .id('plvsa_live_end_icon') + .width(100) + .height(84) + .objectFit(ImageFit.Contain) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 38 + }) + + Text($r('app.string.plvsa_live_end_text')) + .id('plvsa_live_end_text') + .fontSize(24) + .fontColor('#F0F1F5') + .alignRules({ + top: { anchor: 'plvsa_live_end_icon', align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 6 + }) + + Shape() + .id('plvsa_live_end_time_split') + .width(1) + .height(52) + .backgroundColor('#33FFFFFF') + .alignRules({ + top: { anchor: 'plvsa_live_end_text', align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + top: 18 + }) + + Column() { + Text(this.liveTimestampRange) + .fontColor('#CCF0F1F5') + .fontSize(16) + .fontWeight(FontWeight.Bold) + Blank().height(10) + Text($r('app.string.plvsa_live_timestamp_text')) + .fontColor('#CCF0F1F5') + .fontSize(14) + } + .id('plvsa_live_end_timestamp_range') + .alignRules({ + right: { anchor: 'plvsa_live_end_time_split', align: HorizontalAlign.Start }, + center: { anchor: 'plvsa_live_end_time_split', align: VerticalAlign.Center } + }) + .margin({ + right: 25 + }) + + Column() { + Text(this.liveTimeDuration) + .fontColor('#CCF0F1F5') + .fontSize(16) + .fontWeight(FontWeight.Bold) + Blank().height(10) + Text($r('app.string.plvsa_live_duration_text')) + .fontColor('#CCF0F1F5') + .fontSize(14) + } + .id('plvsa_live_end_duration_range') + .alignRules({ + left: { anchor: 'plvsa_live_end_time_split', align: HorizontalAlign.End }, + center: { anchor: 'plvsa_live_end_time_split', align: VerticalAlign.Center } + }) + .margin({ + left: 40 + }) + + Button($r('app.string.plvsa_confirm_dialog_confirm')) + .width(180) + .height(50) + .fontSize(16) + .fontColor('#FFFFFF') + .linearGradient({ + angle: 90, + colors: [ + ['#0080FF', 0], + ['#3399FF', 0] + ] + }) + .borderRadius(25) + .alignRules({ + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom }, + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center } + }) + .margin({ + bottom: 44 + }) + .onClick(() => { + router.back() + }) + } + .width('100%') + .height('100%') + .backgroundColor('#2c2c2c') + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/layouts/live/PLVSALiveLayout.ets b/scenes_streamerAlone/src/main/ets/layouts/live/PLVSALiveLayout.ets new file mode 100644 index 0000000..54f34d1 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/layouts/live/PLVSALiveLayout.ets @@ -0,0 +1,203 @@ +import { + PLVCommonConstants, + PLVLinkMicAnswerInvitationEvent, + PLVLiveSceneSDK, + PLVMemberErrorEvent, + PLVToastUtils +} from '@polyvharmony/live-scenes-sdk'; +import { Disposable, lateInit, MutableObserver } from '@polyvharmony/media-player-sdk'; +import { PLVSAPageDataBus } from '../../common/PLVSAPageDataBus'; +import { PLVSAConfirmDialog } from '../../common/widget/PLVSAConfirmDialog'; +import { PLVSAChatroomLayout } from '../../components/chatroom/PLVSAChatroomLayout'; +import { PLVSALinkMicInvitationLayout } from '../../components/linkmic/widgets/PLVSALinkMicInvitationLayout'; +import { PLVSANetworkDisconnectMaskLayout } from '../../components/misc/PLVSANetworkDisconnectMaskLayout'; +import { PLVSAStatusBarLayout } from '../../components/statusbar/PLVSAStatusBarLayout'; +import { PLVSAToolBarLayout } from '../../components/toolbar/PLVSAToolBarLayout'; + +@Component +export struct PLVSALiveLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly finishStreamDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + hasTitle: false, + content: $r('app.string.plvsa_finish_stream_confirm_dialog_content'), + onClickConfirm: (controller) => { + this.pageDataBus.finishStream(this.sdk) + controller?.close() + } + }), + customStyle: true + }) + private maskLayoutOnTouchIntercept: ((touchEvent: TouchEvent) => HitTestMode) | undefined = undefined + private onBackPressDisposable: Disposable | null = null + + aboutToAppear(): void { + this.sdk.memberManager.startUpdateChannelViewersInterval() + this.onBackPressDisposable = this.pageDataBus.onBackPressHandler.register(10, () => this.onBackPress()) + } + + build() { + Stack() { + LiveEventHandler() + + Tabs({ + index: 1 + }) { + TabContent() { + LiveClearLayout() + } + + TabContent() { + LiveMainLayout() + } + } + .barHeight(0) + .width('100%') + .height('100%') + + PLVSANetworkDisconnectMaskLayout({ + callbackOnTouchIntercept: (callback: (touchEvent: TouchEvent) => HitTestMode) => { + this.maskLayoutOnTouchIntercept = callback + } + }) + .id('plvsa_network_disconnect_mask_layout') + .width('100%') + .height('100%') + .onTouchIntercept((event: TouchEvent) => { + return this.maskLayoutOnTouchIntercept?.(event) ?? HitTestMode.Transparent + }) + } + } + + onBackPress(): boolean { + this.finishStreamDialogController.open() + return true + } + + aboutToDisappear(): void { + this.onBackPressDisposable?.dispose() + this.sdk.memberManager.stopUpdateChannelViewersInterval() + } +} + +@Component +struct LiveMainLayout { + build() { + RelativeContainer() { + PLVSAStatusBarLayout() + .id('plvsa_status_bar_layout') + .width('100%') + .height('100%') + .hitTestBehavior(HitTestMode.Transparent) + + PLVSAToolBarLayout() + .id('plvsa_tool_bar') + .margin({ + right: 8, + bottom: 8 + }) + .alignRules({ + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .hitTestBehavior(HitTestMode.Transparent) + + PLVSAChatroomLayout() + .id('plvsa_chatroom_layout') + .width('100%') + .height('100%') + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .hitTestBehavior(HitTestMode.Transparent) + + PLVSALinkMicInvitationLayout() + .id('plvsa_linkmic_invitation_layout') + .width('100%') + .height('100%') + .hitTestBehavior(HitTestMode.Transparent) + } + .width('100%') + .height('100%') + } +} + +@Component +struct LiveClearLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly finishStreamDialogController = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + hasTitle: false, + content: $r('app.string.plvsa_finish_stream_confirm_dialog_content'), + onClickConfirm: (controller) => { + this.pageDataBus.finishStream(this.sdk) + controller?.close() + } + }), + customStyle: true + }) + + build() { + RelativeContainer() { + Image($r('app.media.plvsa_status_bar_close')) + .id('plvsa_status_bar_finish_stream_icon') + .width(32) + .height(32) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End } + }) + .margin({ + top: 8, + right: 8 + }) + .onClick(() => { + this.finishStreamDialogController.open() + }) + } + .width('100%') + .height('100%') + } +} + +@Component +struct LiveEventHandler { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.sdk.linkmicManager.viewerAnswerInvitationEvent.observe(it => this.onLinkMicViewerAnswerInvitation(it)) + .pushTo(this.observers) + this.sdk.memberManager.errorEvent.observe(it => this.onMemberErrorEvent(it)) + .pushTo(this.observers) + } + + build() { + } + + private onLinkMicViewerAnswerInvitation(event: PLVLinkMicAnswerInvitationEvent) { + const viewerName = event.viewer.viewerName.value + const accept = event.accept + if (viewerName !== undefined && !accept) { + PLVToastUtils.shortShow($r('app.string.plvsa_linkmic_invitation_not_accept', viewerName)) + } + } + + private onMemberErrorEvent(event: PLVMemberErrorEvent) { + switch (event.code) { + case PLVMemberErrorEvent.REACH_LINKMIC_LIMIT: { + PLVToastUtils.shortShow($r('app.string.plvsa_linkmic_reach_limit')); + break; + } + default: + } + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/ets/layouts/startup/PLVSAStartUpLayout.ets b/scenes_streamerAlone/src/main/ets/layouts/startup/PLVSAStartUpLayout.ets new file mode 100644 index 0000000..cd58de7 --- /dev/null +++ b/scenes_streamerAlone/src/main/ets/layouts/startup/PLVSAStartUpLayout.ets @@ -0,0 +1,357 @@ +import { + PLVCommonConstants, + PLVLinkMicCameraFacing, + PLVLiveSceneSDK, + PLVScheduledTask, + PLVUserType +} from '@polyvharmony/live-scenes-sdk'; +import { Disposable, lateInit, lazy, MutableObserver, seconds } from '@polyvharmony/media-player-sdk'; +import { PLVSAPageDataBus, PLVSAStreamerStage } from '../../common/PLVSAPageDataBus'; +import { PLVSAMoreBitRateButton } from '../../components/more/widgets/PLVSAMoreBitRateButton'; +import { PLVSAMoreCameraFacingButton } from '../../components/more/widgets/PLVSAMoreCameraFacingButton'; +import { PLVSAMoreCameraMirrorButton } from '../../components/more/widgets/PLVSAMoreCameraMirrorButton'; +import { PLVSAMoreMixLayoutButton } from '../../components/more/widgets/PLVSAMoreMixLayoutButton'; +import { PLVSAMoreOrientationButton } from '../../components/more/widgets/PLVSAMoreOrientationButton'; +import { PLVSAMoreResolutionRatioButton } from '../../components/more/widgets/PLVSAMoreResolutionRatioButton'; +import { router } from '@kit.ArkUI'; +import { PLVSAConfirmDialog } from '../../common/widget/PLVSAConfirmDialog'; +import { PLVSAMoreLayoutActionSwitcher } from '../../components/more/PLVSAMoreLayout'; + +@Component +export struct PLVSAStartUpLayout { + @LocalStorageLink('sdk') sdk: PLVLiveSceneSDK = lateInit() + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + private readonly recoverStreamDialog = new CustomDialogController({ + builder: PLVSAConfirmDialog({ + hasTitle: false, + content: $r('app.string.plvsa_last_stream_not_finish_hint'), + cancelText: $r('app.string.plvsa_last_stream_not_finish_cancel_recover'), + confirmText: $r('app.string.plvsa_last_stream_not_finish_confirm_recover'), + onClickCancel: (controller) => { + this.sdk.streamerManager.finishStream() + controller?.close() + }, + onClickConfirm: (controller) => { + this.recoverLiveStream() + controller?.close() + } + }), + autoCancel: false, + customStyle: true + }) + @State liveTitle: string = "" + @State countDownLayoutVisible: boolean = false + @State isPortrait: boolean = true + private readonly actionSwitcher = lazy(() => new PLVSAMoreLayoutActionSwitcher(this.sdk)) + private recoverStream: boolean = false + private countDownHandler: PLVSAStartUpCountDownHandler | null = null + private observers: MutableObserver[] = [] + + aboutToAppear(): void { + this.liveTitle = this.sdk.channelData.streamerData?.channelName ?? "" + this.pageDataBus.isPortrait.observe(it => this.isPortrait = it).pushTo(this.observers) + this.checkLastStreamNotFinish() + } + + private checkLastStreamNotFinish() { + const isTeacher = this.sdk.channelData.viewerType === PLVUserType.USERTYPE_TEACHER + const isLastStreamNotFinish = this.sdk.channelData.streamerData?.liveStatus === true + if (isTeacher && isLastStreamNotFinish) { + this.recoverStreamDialog.open() + } + } + + build() { + Stack() { + RelativeContainer() { + Image($r('app.media.plvsa_startup_back_icon')) + .id('plvsa_startup_back_icon') + .width(36) + .height(36) + .alignRules({ + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top }, + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start } + }) + .margin({ + left: 24, + top: 9 + }) + .onClick(() => { + router.back() + }) + + Column() { + TextArea({ + placeholder: $r('app.string.plvsa_startup_title_placeholder'), + text: $$this.liveTitle + }) + .width('100%') + .textAlign(TextAlign.Center) + .backgroundColor('transparent') + .placeholderColor("#99F0F1F5") + .fontColor("#F0F1F5") + .fontSize(18) + .margin({ + left: 24, + right: 24 + }) + .borderRadius(0) + .padding(0) + .maxLength(150) + + Divider() + .vertical(false) + .width('100%') + .color("#99FFFFFF") + .opacity(0.7) + .strokeWidth(2) + .margin({ + top: 12 + }) + } + .id('plvsa_startup_title_layout') + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End }, + top: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Top } + }) + .width('100%') + .padding({ + left: 48, + right: 48 + }) + .margin({ + top: 72 + }) + + Flex({ + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Center + }) { + PLVSAMoreCameraFacingButton({ + iconPadding: 12 + }) + .width(62) + .padding({ + top: 6, + bottom: 6 + }) + + PLVSAMoreCameraMirrorButton({ + iconPadding: 12 + }) + .width(62) + .padding({ + top: 6, + bottom: 6 + }) + + PLVSAMoreBitRateButton({ + iconPadding: 12 + }) + .width(62) + .padding({ + top: 6, + bottom: 6 + }) + + PLVSAMoreOrientationButton({ + iconPadding: 12 + }) + .width(62) + .padding({ + top: 6, + bottom: 6 + }) + + if (this.actionSwitcher.value.showMixLayoutButton) { + PLVSAMoreMixLayoutButton({ + iconPadding: 12 + }) + .width(62) + .padding({ + top: 6, + bottom: 6 + }) + } + + if (this.actionSwitcher.value.showResolutionRatioButton && !this.isPortrait) { + PLVSAMoreResolutionRatioButton({ + iconPadding: 12 + }) + .width(62) + .padding({ + top: 6, + bottom: 6 + }) + } + } + .id('plvsa_startup_setting_layout') + .alignRules({ + middle: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Center }, + bottom: { anchor: "plvsa_startup_stream_start_button", align: VerticalAlign.Top } + }) + .padding({ + left: 24, + right: 24 + }) + .margin({ + bottom: 40 + }) + + Button($r('app.string.plvsa_startup_start_live')) + .id('plvsa_startup_stream_start_button') + .width(280) + .height(50) + .fontColor("#FFFFFF") + .fontSize(16) + .backgroundColor("#0080FF") + .margin({ + bottom: 20 + }) + .alignRules({ + left: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.Start }, + right: { anchor: PLVCommonConstants.CONTAINER, align: HorizontalAlign.End }, + bottom: { anchor: PLVCommonConstants.CONTAINER, align: VerticalAlign.Bottom } + }) + .onClick(() => { + this.countDownHandler?.startCountDown?.() + }) + } + .visibility(this.countDownLayoutVisible ? Visibility.None : Visibility.Visible) + .width('100%') + .height('100%') + + PLVSAStartUpCountDownLayout({ + callbackHandler: (handler: PLVSAStartUpCountDownHandler | null) => { + this.countDownHandler = handler + }, + onCountDownStart: () => { + this.countDownLayoutVisible = true + }, + onCountDownFinish: () => { + this.countDownLayoutVisible = false + this.startLiveStream() + }, + onCountDownCancel: () => { + this.countDownLayoutVisible = false + } + }) + .id('plvsa_startup_count_down_layout') + .width('100%') + .height('100%') + .hitTestBehavior(HitTestMode.Transparent) + } + .width('100%') + .height('100%') + } + + private async recoverLiveStream() { + await this.pageDataBus.recoverSetting.recoverFromLocal(this.sdk) + this.countDownHandler?.startCountDown?.() + } + + private async startLiveStream() { + this.pageDataBus.streamerStage.setValue(PLVSAStreamerStage.LIVE) + const originLiveTitle = this.sdk.channelData.streamerData?.channelName + if (this.liveTitle !== originLiveTitle) { + await this.sdk.streamerManager.updateChannelName(this.liveTitle) + } + await this.sdk.streamerManager.startStream(this.recoverStream) + this.pageDataBus.recoverSetting.update({ + isPortrait: this.pageDataBus.isPortrait.value, + bitRateIndex: this.sdk.streamerManager.currentBitRate.value?.index, + isEnableCamera: this.sdk.linkmicManager.localLinkMicViewer.value?.isVideoEnable.value, + isFrontCamera: this.sdk.linkmicManager.cameraFacing.value !== PLVLinkMicCameraFacing.BACK + }) + } + + aboutToDisappear(): void { + MutableObserver.disposeAll(this.observers) + this.observers = [] + } +} + +@Component +struct PLVSAStartUpCountDownLayout { + callbackHandler?: (handler: PLVSAStartUpCountDownHandler | null) => void + onCountDownStart?: () => void + onCountDownFinish?: () => void + onCountDownCancel?: () => void + @Consume('pageDataBus') pageDataBus: PLVSAPageDataBus + @State visible: boolean = false + @State countDownText: string = "" + private countDown: number = 0 + private countDownTask: PLVScheduledTask | undefined = undefined + private onBackPressDisposable: Disposable | undefined = undefined + + aboutToAppear(): void { + const handler = new PLVSAStartUpCountDownHandler() + handler.startCountDown = () => { + this.startCountDown() + } + this.callbackHandler?.(handler) + this.onBackPressDisposable = this.pageDataBus.onBackPressHandler.register(10, () => this.onBackPress()) + } + + build() { + if (this.visible) { + Stack() { + Text(this.countDownText) + .width(100) + .height(100) + .borderRadius(100) + .backgroundColor("#66000000") + .fontColor('#FFFFFF') + .fontSize(48) + .textAlign(TextAlign.Center) + } + .width('100%') + .height('100%') + .backgroundColor('#99000000') + } + } + + private startCountDown() { + if (this.countDownTask !== undefined) { + this.onCountDownCancel?.() + this.stopCountDown() + } + this.countDown = 4 + this.countDownTask = new PLVScheduledTask(() => { + this.countDown -= 1 + this.countDownText = this.countDown.toString() + this.visible = this.countDown > 0 + if (this.countDown <= 0) { + this.stopCountDown() + this.onCountDownFinish?.() + } + }, 0, seconds(1).toMillis()) + this.onCountDownStart?.() + this.countDownTask.start() + } + + private stopCountDown() { + this.countDownTask?.cancel() + this.countDownTask = undefined + } + + onBackPress(): boolean { + if (this.visible) { + this.stopCountDown() + this.visible = false + this.onCountDownCancel?.() + return true + } + return false + } + + aboutToDisappear(): void { + this.callbackHandler?.(null) + this.onBackPressDisposable?.dispose() + } +} + +class PLVSAStartUpCountDownHandler { + startCountDown?: () => void +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/module.json5 b/scenes_streamerAlone/src/main/module.json5 new file mode 100644 index 0000000..0a4bfdf --- /dev/null +++ b/scenes_streamerAlone/src/main/module.json5 @@ -0,0 +1,14 @@ +{ + "module": { + "name": "scenes_streamerAlone", + "type": "har", + "description": "$string:shared_desc", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ]/*, + "deliveryWithInstall": true, + "pages": "$profile:main_pages"*/ + } +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/resources/base/element/color.json b/scenes_streamerAlone/src/main/resources/base/element/color.json new file mode 100644 index 0000000..1bbc9aa --- /dev/null +++ b/scenes_streamerAlone/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/scenes_streamerAlone/src/main/resources/base/element/string.json b/scenes_streamerAlone/src/main/resources/base/element/string.json new file mode 100644 index 0000000..d17081d --- /dev/null +++ b/scenes_streamerAlone/src/main/resources/base/element/string.json @@ -0,0 +1,664 @@ +{ + "string": [ + { + "name": "shared_desc", + "value": "description" + }, + { + "name": "plv_chat_pin", + "value": "Pin" + }, + { + "name": "plv_chat_pin_cancel", + "value": "Unpin" + }, + { + "name": "plv_red_paper_get", + "value": "Click to receive" + }, + { + "name": "plv_red_paper_red_pack_hint", + "value": "Password red envelope coming soon" + }, + { + "name": "plvsa_chat_answer", + "value": "Reply" + }, + { + "name": "plvsa_chat_cancel_close_room_text", + "value": "Unmute all" + }, + { + "name": "plvsa_chat_cancel_close_room_toast", + "value": "Mute all canceled" + }, + { + "name": "plvsa_chat_close_room_text", + "value": "Mute all" + }, + { + "name": "plvsa_chat_close_room_toast", + "value": "Mute all enabled" + }, + { + "name": "plvsa_chat_copy", + "value": "Copy" + }, + { + "name": "plvsa_chat_copy_success", + "value": "Copy success" + }, + { + "name": "plvsa_chat_full_text", + "value": "Full text" + }, + { + "name": "plvsa_chat_input_tips_chat", + "value": "Join the chat" + }, + { + "name": "plvsa_chat_input_tips_chatroom_close", + "value": "Chatroom is closed" + }, + { + "name": "plvsa_chat_input_tips_focus", + "value": "In focus mode" + }, + { + "name": "plvsa_chat_input_tips_quiz", + "value": "Initiate a question" + }, + { + "name": "plvsa_chat_me", + "value": "%s(me)%s" + }, + { + "name": "plvsa_chat_more", + "value": "More" + }, + { + "name": "plvsa_chat_playback_tips", + "value": "Chat replay is on, showing historical messages" + }, + { + "name": "plvsa_chat_quiz_channel", + "value": "Question Channel" + }, + { + "name": "plvsa_chat_quiz_default_tips", + "value": "You have entered the exclusive question channel, and the content of the question will not be made public" + }, + { + "name": "plvsa_chat_restrict_max_viewer_hint", + "value": "The live room is too popular, please come back later" + }, + { + "name": "plvsa_chat_send", + "value": "Send" + }, + { + "name": "plvsa_chat_toast_account_login_elsewhere", + "value": "The current account has been logged in elsewhere, you will be logged out of this live room" + }, + { + "name": "plvsa_chat_toast_been_kicked", + "value": "You have been kicked out of the chatroom by the administrator!" + }, + { + "name": "plvsa_chat_toast_chatroom_close", + "value": "Chatroom has been closed" + }, + { + "name": "plvsa_chat_toast_chatroom_open", + "value": "Chatroom has been opened" + }, + { + "name": "plvsa_chat_toast_history_load_failed", + "value": "History loading failed%s" + }, + { + "name": "plvsa_chat_toast_logging", + "value": "Chatroom logging" + }, + { + "name": "plvsa_chat_toast_login_failed", + "value": "Chatroom login failed" + }, + { + "name": "plvsa_chat_toast_login_success", + "value": "Chatroom login successful" + }, + { + "name": "plvsa_chat_toast_reconnect_success", + "value": "Chatroom reconnected successfully" + }, + { + "name": "plvsa_chat_toast_reconnecting", + "value": "Chatroom reconnecting" + }, + { + "name": "plvsa_chat_toast_send_text_empty", + "value": "The sending content cannot be empty!" + }, + { + "name": "plvsa_chat_view_new_msg", + "value": "News" + }, + { + "name": "plvsa_chat_welcome_join", + "value": "welcome %s join" + }, + { + "name": "plvsa_chat_welcome_join_multi", + "value": "welcome %s and other %s people join" + }, + { + "name": "plvsa_confirm_dialog_cancel", + "value": "Cancel" + }, + { + "name": "plvsa_confirm_dialog_confirm", + "value": "Confirm" + }, + { + "name": "plvsa_confirm_dialog_content", + "value": "Hint" + }, + { + "name": "plvsa_confirm_dialog_title", + "value": "Hint" + }, + { + "name": "plvsa_finish_stream_confirm_dialog_content", + "value": "Confirm to end the live stream?" + }, + { + "name": "plvsa_last_stream_not_finish_cancel_recover", + "value": "End live stream" + }, + { + "name": "plvsa_last_stream_not_finish_confirm_recover", + "value": "Resume live stream" + }, + { + "name": "plvsa_last_stream_not_finish_hint", + "value": "Abnormal exit before detection\nResume live stream?" + }, + { + "name": "plvsa_linkmic_close_confirm_content", + "value": "Closing will hang up all current calls" + }, + { + "name": "plvsa_linkmic_close_confirm_title", + "value": "Confirm disconnecting the call?" + }, + { + "name": "plvsa_linkmic_guest_cancel_request_text", + "value": "Call pending. Cancel call?" + }, + { + "name": "plvsa_linkmic_guest_leave_linkmic_text", + "value": "Confirm disconnecting the call?" + }, + { + "name": "plvsa_linkmic_guest_state_joined", + "value": "In a call" + }, + { + "name": "plvsa_linkmic_guest_state_not_joined", + "value": "Not in a call" + }, + { + "name": "plvsa_linkmic_hang_up_all_confirm_content", + "value": "Hang up all audiences?" + }, + { + "name": "plvsa_linkmic_hang_up_all_text", + "value": "Hang up audiences" + }, + { + "name": "plvsa_linkmic_hang_up_all_toast", + "value": "Audiences have been hanged up" + }, + { + "name": "plvsa_linkmic_invitation_accept_text", + "value": "Accept" + }, + { + "name": "plvsa_linkmic_invitation_camera", + "value": "Camera" + }, + { + "name": "plvsa_linkmic_invitation_camera_closed_text", + "value": "The camera has been off" + }, + { + "name": "plvsa_linkmic_invitation_dialog_accept", + "value": "Accept" + }, + { + "name": "plvsa_linkmic_invitation_dialog_content", + "value": "The lecturer is inviting you to speak (%ss)" + }, + { + "name": "plvsa_linkmic_invitation_dialog_refuse", + "value": "Refuse" + }, + { + "name": "plvsa_linkmic_invitation_dialog_title", + "value": "Prompt" + }, + { + "name": "plvsa_linkmic_invitation_microphone", + "value": "Microphone" + }, + { + "name": "plvsa_linkmic_invitation_not_accept", + "value": "%s did not accept your invitation" + }, + { + "name": "plvsa_linkmic_invitation_privacy_notify", + "value": "Video Call will collect portrait information, confirm on the microphone as consent" + }, + { + "name": "plvsa_linkmic_invitation_refuse_text", + "value": "Not Now(%ss)" + }, + { + "name": "plvsa_linkmic_invitation_title_audio", + "value": "Inviting you to join the audio call" + }, + { + "name": "plvsa_linkmic_invitation_title_video", + "value": "Inviting you to join the video call" + }, + { + "name": "plvsa_linkmic_member_control_full_screen", + "value": "Full screen" + }, + { + "name": "plvsa_linkmic_member_control_grant_speaker_confirm_content", + "value": "There is currently a lecturer presenting. Confirming will replace the current lecturer with a new one" + }, + { + "name": "plvsa_linkmic_member_control_grant_speaker_confirm_title", + "value": "Are you sure you want to grant him the lecture permission?" + }, + { + "name": "plvsa_linkmic_member_control_hang_up_linkmic", + "value": "Hang up" + }, + { + "name": "plvsa_linkmic_member_control_hang_up_linkmic_confirm_title", + "value": "Confirm disconnecting them from the call?" + }, + { + "name": "plvsa_linkmic_member_control_withdraw_speaker_confirm_content", + "value": "The lecture\u0027s screen sharing will automatically end after removal" + }, + { + "name": "plvsa_linkmic_member_control_withdraw_speaker_confirm_title", + "value": "Are you sure you want to withdrawn his lecture permission?" + }, + { + "name": "plvsa_linkmic_mode_audio", + "value": "Audio call" + }, + { + "name": "plvsa_linkmic_mode_video", + "value": "Video call" + }, + { + "name": "plvsa_linkmic_new_request_check_text", + "value": "View" + }, + { + "name": "plvsa_linkmic_new_request_hint_text", + "value": "Someone is requesting to join the call" + }, + { + "name": "plvsa_linkmic_no_stream_place_holder_text", + "value": "No live streaming at the moment" + }, + { + "name": "plvsa_linkmic_reach_limit", + "value": "No more connections available" + }, + { + "name": "plvsa_linkmic_setting_default_linkmic_type", + "value": "Default voice chat type" + }, + { + "name": "plvsa_linkmic_setting_default_setting_hint", + "value": "To set a default voice chat method, adjust the settings in the Channel \u003e Role Permissions \u003e Functional Configuration" + }, + { + "name": "plvsa_linkmic_setting_linkmic_type_audio", + "value": "Audio" + }, + { + "name": "plvsa_linkmic_setting_linkmic_type_video", + "value": "Video" + }, + { + "name": "plvsa_linkmic_setting_not_open", + "value": "Not activated yet, please contact the administrator" + }, + { + "name": "plvsa_linkmic_setting_switch_hint", + "value": "Note: Before switching voice chat type, you should make sure nobody connected" + }, + { + "name": "plvsa_linkmic_setting_switch_type_hang_up_viewer_dialog_confirm", + "value": "Switch and hang up viewers" + }, + { + "name": "plvsa_linkmic_setting_switch_type_hang_up_viewer_dialog_content", + "value": "Can not switch voice chat type because viewers are connecting. To continue, all connected viewers will be hanged up. Confirm to switch type?" + }, + { + "name": "plvsa_linkmic_setting_text", + "value": "Voice chat setting" + }, + { + "name": "plvsa_linkmic_viewer_raise_hand_disable_toast", + "value": "Viewer voice chat disabled" + }, + { + "name": "plvsa_linkmic_viewer_raise_hand_enable_toast", + "value": "Viewer voice chat enabled" + }, + { + "name": "plvsa_linkmic_viewer_raise_hand_text", + "value": "Allow voice chat" + }, + { + "name": "plvsa_linkmic_viewer_raise_hand_timeout_toast", + "value": "Weak network signal, activation failed. Check your connection!" + }, + { + "name": "plvsa_live_duration_text", + "value": "Live duration" + }, + { + "name": "plvsa_live_end_text", + "value": "Live has ended" + }, + { + "name": "plvsa_live_timestamp_text", + "value": "Live time" + }, + { + "name": "plvsa_network_disconnect_mask_hint", + "value": "Network down, live stream paused" + }, + { + "name": "plvsa_member_ban_confirm_title", + "value": "Are you sure you want to ban %s?" + }, + { + "name": "plvsa_member_hang_up_linkmic_confirm_title", + "value": "Confirm disconnecting the call?" + }, + { + "name": "plvsa_member_kick_confirm_content", + "value": "Banned from rejoining for 24 hours after being kicked out" + }, + { + "name": "plvsa_member_kick_confirm_title", + "value": "Are you sure you want to kick %s?" + }, + { + "name": "plvsa_member_more_ban_chat", + "value": "Ban" + }, + { + "name": "plvsa_member_more_grant_speaker_permission", + "value": "Grant lecture permission" + }, + { + "name": "plvsa_member_more_kick_out", + "value": "Kick out" + }, + { + "name": "plvsa_member_more_unban_chat", + "value": "Unban" + }, + { + "name": "plvsa_member_more_withdraw_speaker_permission", + "value": "Withdrawn lecture permission" + }, + { + "name": "plvsa_member_online_count", + "value": "Online (%s)" + }, + { + "name": "plvsa_more_bitrate_description_text", + "value": "Resolution: %s, Bitrate: %s, Frame Rate: %s" + }, + { + "name": "plvsa_more_bitrate_select_title", + "value": "Clarity settings" + }, + { + "name": "plvsa_more_camera", + "value": "Camera" + }, + { + "name": "plvsa_more_camera_facing_switch", + "value": "Turn" + }, + { + "name": "plvsa_more_camera_mirror", + "value": "Mirror" + }, + { + "name": "plvsa_more_layout_title", + "value": "More" + }, + { + "name": "plvsa_more_microphone", + "value": "Microphone" + }, + { + "name": "plvsa_more_mix_layout", + "value": "Mix layout" + }, + { + "name": "plvsa_more_mix_layout_select_title", + "value": "Mix layout" + }, + { + "name": "plvsa_more_mix_layout_type_single", + "value": "Single" + }, + { + "name": "plvsa_more_mix_layout_type_speaker", + "value": "Speaker" + }, + { + "name": "plvsa_more_mix_layout_type_tile", + "value": "Tile" + }, + { + "name": "plvsa_more_orientation", + "value": "Orient" + }, + { + "name": "plvsa_more_push_resolution_ratio", + "value": "Ratio" + }, + { + "name": "plvsa_more_share_action_cancel", + "value": "Cancel" + }, + { + "name": "plvsa_more_share_action_copy_link", + "value": "Copy link" + }, + { + "name": "plvsa_more_share_action_save_image", + "value": "Save picture" + }, + { + "name": "plvsa_more_share_action_save_image_fail_toast", + "value": "Save picture fail" + }, + { + "name": "plvsa_more_share_action_save_image_success_toast", + "value": "Save picture success" + }, + { + "name": "plvsa_more_share_title", + "value": "Share" + }, + { + "name": "plvsa_push_downgrade_fluency_desc", + "value": "When network condition is poor, video fluency is prioritized but may cause lower clarity" + }, + { + "name": "plvsa_push_downgrade_fluency_title", + "value": "Fluency priority" + }, + { + "name": "plvsa_push_downgrade_notify_action", + "value": "Switch now" + }, + { + "name": "plvsa_push_downgrade_notify_switch_success", + "value": "Switched to fluency priority mode" + }, + { + "name": "plvsa_push_downgrade_notify_text", + "value": "The network condition is currently poor. It\u0027s recommended to switch to fluency mode" + }, + { + "name": "plvsa_push_downgrade_preference_title", + "value": "Weak net" + }, + { + "name": "plvsa_push_downgrade_quality_desc", + "value": "When network condition is poor, video quality is prioritized but may cause lagging" + }, + { + "name": "plvsa_push_downgrade_quality_title", + "value": "Quality priority" + }, + { + "name": "plvsa_red_paper_dot", + "value": ", " + }, + { + "name": "plvsa_red_paper_get", + "value": "Click to receive" + }, + { + "name": "plvsa_red_paper_send_msg", + "value": "%s sent a " + }, + { + "name": "plvsa_reward_gift_give", + "value": "given" + }, + { + "name": "plvsa_reward_give", + "value": "given%s" + }, + { + "name": "plvsa_reward_money_give", + "value": "reward" + }, + { + "name": "plvsa_reward_money_give_unit_cny", + "value": "yuan" + }, + { + "name": "plvsa_startup_start_live", + "value": "Start live" + }, + { + "name": "plvsa_startup_title_placeholder", + "value": "Click to enter live title" + }, + { + "name": "plvsa_status_bar_channel_info", + "value": "Channel info" + }, + { + "name": "plvsa_status_bar_channel_info_channel_id", + "value": "Channel id:" + }, + { + "name": "plvsa_status_bar_channel_info_copy", + "value": "Copy" + }, + { + "name": "plvsa_status_bar_channel_info_copy_success", + "value": "Copied" + }, + { + "name": "plvsa_status_bar_channel_info_live_title", + "value": "Live title:" + }, + { + "name": "plvsa_status_bar_channel_info_start_time", + "value": "Start time:" + }, + { + "name": "plvsa_status_bar_channel_info_start_time_not_set", + "value": "Not set" + }, + { + "name": "plvsa_status_bar_network_delay_text", + "value": "Network latency: %sms" + }, + { + "name": "plvsa_status_bar_network_loss_rate_text", + "value": "Packet loss rate: ↑%s% ↓%s%" + }, + { + "name": "plvsa_status_bar_network_quality_bad", + "value": "Network bad" + }, + { + "name": "plvsa_status_bar_network_quality_disconnect", + "value": "Network disconnected" + }, + { + "name": "plvsa_status_bar_network_quality_excellent", + "value": "Network excellent" + }, + { + "name": "plvsa_status_bar_network_quality_good", + "value": "Network good" + }, + { + "name": "plvsa_status_bar_network_quality_poor", + "value": "Network poor" + }, + { + "name": "plvsa_status_bar_network_quality_unknown", + "value": "Unknown Network" + }, + { + "name": "plvsa_status_bar_network_quality_very_bad", + "value": "Network very bad" + }, + { + "name": "plvsa_status_bar_notification", + "value": "Notify" + }, + { + "name": "plvsa_status_bar_notify_camera_disabled", + "value": "Your camera is off" + }, + { + "name": "plvsa_status_bar_notify_camera_microphone_disabled", + "value": "Your camera and microphone are turned off" + }, + { + "name": "plvsa_status_bar_notify_microphone_disabled", + "value": "Your microphone is off" + } + ] +} diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_emotion_image_bar_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_emotion_image_bar_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0530d21b85ff9734369707ec6c782b1e6755c428 GIT binary patch literal 3479 zcmWkwc{J4h7am&}w7g}F-jrUlluFVRAxm}!6OtwSM8-BU)|pba=oKN^!x&2pBaNL3 zW0?s`S@*0YYhdMeSS`UN{`7d}o6iQ5kTBuOm1L*m4sO1&Z zP!Hu6f}j}4FBA&JLd|thKroc@2pXY5IYkf}1G?IwzHW&22BMJvBjg6q*9*PtgI+a3 z)K}1lA?W@?sG$+KW1yT|sOT9)r}JDeP=4|56kOkM9yWp-e-|>cf*er5=_cFi2C#Pn zkCK3MAi!YR*DOKQL&(|@+=~Z~Q^6fHpwroUw!A z21yS;!j0xVKyZsTP`I z>?!~TsgS)N_mUBq=m6L_(Ao$(Ujbh?@U{nx(AbwPcw^llGm{s92Km`ws+aA0ljH3L zDAjB|Q(kl^Xl{l~P=Hj*wX_1H0`P{iV}abcW($)31wGvy9b;Zz24ro?%OHS0Di<5P zf;z2?vpp*h~ z5%@L?8i)XCz2k5l#0GWx0?ay@TmXKzY zo=qWkWmyfP1o`+5>wgr#4L_!mnj%*$lBMtPnE;oRqu-yhbbh?Fq3=2WGa&~ihiEwI5MiPcF5=I z2)%prOKz$?^?0YH)_Dn0(FV$n=(}9esne#)RT62*CskFyDp`N5_Z-OF^3n>&rBLMr zEO^hWL(ia~o4HT_z85G`@71yKzdy{;IU9cdi@)65tgSB+CQwnz=PRt% zB@`}W7tC{P<-dH{m}uyd3L#k8-MnHT`&2hPOp(Zk{}mnE-tsZ2nYIw~T7EhHat4~J zb4gjJEB69jMJw-?qIx;WewbV-EhS|hm9R0ry6{HG-tAbG>dBKOs$fu=c_V!NhKmXy-gqo7~WfJ0Qwr@;Zj?8doCJCEtlzi4XARI%;X7<$H@EdWh zi|k_bdKSK)`u6kua@1%H*{z~G8O=zLdxk7bwiRhy^c7o42n@dcGE;?EAG$MMM;z(X zANlk9)M?W#{YS#J@61^Oo*bo6egQ4tGKlG`sMBlDR4B%P~u+GgeHV5?f&0r&OQ!C^ZU z(p2G>gnGD<1;XN=YTKaQ+96T69UVqh_6iC;OKRhCV~*H7%aP7s{Ql2^uF$4Cv+~W2 zV=IRo*UcSEY_s|s1cLUgd-?iuYooHFoSbA$bVXQ|OrP7gJZVU!`LD3y;qxU7`x`B) zo6eW=^wI~+vmSj%i;0CHRHf$dLN!($uhn&RPidcSmL2jnDpIxk%h6CdsG7ikC{*N< zRgQ_U?BT;No0Dpqk`OT^X-N9Gtwc>?4S7>%`z61FQ3$&jmHIXbX?L=T;`o|xKkvyI z!JCLn?4le{HjY(KARhGJJS;*D|GoCZ zKsN?Ig8OMX>=QUQFg1(U#jZ73N=Yw%H(`WbAflEj=(35<`-aL$Vso{cU;)Q}_D^=U zU7<9MhD4@6W|B&nv%zkyd;E>VSOQK}m63G3i&b?dHZZ}mb1wt6BLim&j(co8H_gx_ zoxQD9=6iYP0#Qk|_|Fe}RTEvxiDQO}RXxJR?Kc&JC7XI|2DRY4*6M2i<ALqguqr5BVpoO-3h-qK%DN0)g4cykR(9bt7)=(DzyM65fG=M$z$DqM?8#%DjE+ z#RbXUV<{O|E>}fF5D-|# z9THfTl`l{Jm5dtxNUoqQ&x~SaANhH#0%qc?Sjm0xwxa>2|d<&sM5fKpwT zoR2H2X+2JHwsA$IuGB7$w=Q~spCkg}ZAZs8t+^qupIeyXM0qRS`DxEeN!^N&!{IWU z=PgD!A97&@?gZ=MB-~QLa`$cpJnpr>v-)k_zHhNIv{FcH#2BbpR8Sqdx|=+`f4c`lC)?qlt{eZ6~c%ag2c8R&zD>LD7lEKgOk@vr8N zBW`CgDg^sLog=McV<~@CTCVekY|zst7;pvWH;`juq>d#SO3AVbsOt0Da z-R{W&f7As^^2*lA`}w|XQf6YL^mETeSy@@UIf2yv^GW6DRCTG7#Z4Z^i#cc1NLNUz z2_Zk{_^$TKZR=^mBSK!y$oI;UIA1dwLueY0zwKKhR7^VvD5=#e1y`yvo^7?GQzPksdGLEV?qH=i;2oZ~e# z{P`oU*sFUUuDhV_=IXYg8&)x&A}AfHNrAT2aEAtGemq=vjzkpWM+v)qwk|IqaF<0! zr@EcQd!zMyDs+Q?|8Boxm`eP_HA5lP?`W(YRp~#~KXOWaC>l&iqDIsv%VWFaC>Dav zC=HT=f-x zOTL05H>toAUrRlG%PC$}O+gAf$sD>S#?qYPuC7j(q?J7tbENWnX!s33J0IPgD0JrL zL@a5CDt&G(L%%&Y+gMs`Eq!{Qw1#2$d7pG<+`UhQaeLw%gv47#-j{!$@!seSpIL$j zWIb(1OJ_+ft^ROo^4}O`dh}5D;l`p*7SQwR6%^QPc9Upyz*^F)mNmIbA9r!je}_kB z)4#`PK@}X-1%GPMJdQ6vo5DMm`%dhj>pOJE7Ui>wM&~V$SN8&b*2?AzeE9LT?qw&w zy~w?xsJ)*#MBAZ1i|1Zx8x=Yhtz)4S8j+YgQncLGdSk$DHaAbBDHLp1M@BO*_R~Ht uoSTk}jYr_RuD@hopPe=9G==_VKrq&AuOm_^+UVVH5@u#>ZB%FILHIuuDo0%a literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_input_emotion_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_input_emotion_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e05dcd3597777536942d0226489913d18c986f4e GIT binary patch literal 970 zcmV;*12z1KP)-C6E z=w{id5ChjFf**>=9jSEmOvV;it|>4VI-twy6y31Fa#3KN*V&$rx>Dvg%d`b_`Q4De zU!pI6>viw=X}Jpse?-= zcP66TPX4OIVPoF309*cwW!{;9LgQ11ZyWjliWH;gi8?&6+b+)-E6Y>?dVUO(PcrWh z2+tL|7knypDt6-3mOZ#~XIJoET3(rC5iG}W&Yzx#F_wePLgyCq8o~B9Qu0wXQFzAq z>QJ#Gh#Jc=T;yrtGRAVSX{$ThjyAoMG+nFKDJlKT16-pv=EwodF@7e^768Du^I^2Y zydY%d8+NkvFU$kPk+)-xL`)$7wyh813-f|N`-{nF!k7oxL!2DGDRv@}!?xD+5D$mR z06PJ~Gaq6P*e(LI&AcFF)%%z%o#Zm}W(C+Tc3_`*K}cj%OcpFMZ&rY9mu4nqUJ(Dt z0+xyeXyyfR@lz;ph^w#Bwp5)WT@UfZYt-*h462Lp$u*j-GcSlxA(O809XryNpo{eb zr9!sKydZ+DL~0(fBdtkvvHs4j1Td+Y69bnea^J?BIU_*_bg}-<%^WbPoi6jcP@0;D ztQWSTw9|kJywFI5Ua(V*N!kzA2Sj_J0Ya~o60P}Gi*UWuJnM`8N(nT1smE3~ITMhn zOAC6bf6e^X$lYg^O&7Urw{8(QjJQ#7ExI~^cEqH3w%4xkstznrd{)_Yi_A7*lVv&~ zpWTP8J=kKID6oqtcEX;C_@5RL`RO?CVbe+S^Ejv7$KA(yMX{>`WHHA_-RFGtw3!4s zh<7D&gOi1feO_M{hZaG2p742n09~wqX0XLfs--RYg;OE2vNEUcHaZumJimdaOQDN( sKQW!Ug^IBaDh%?810{Qv*}07*qoM6N<$g8g03rT_o{ literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_msg.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_msg.png new file mode 100644 index 0000000000000000000000000000000000000000..fcad34a499b2cb75ff99a8cacff71da5d9ed00b0 GIT binary patch literal 742 zcmV|qe;xY%(3Edt8a?%f*o(O^n89G(cT({h#LwY1hrP85yD=NW zYuLKd5Q*p3@DkqL%LzL0LkMnS(`rK`-kZV`?xJI<=F`#m5YIL$MB?8W-f*f~(|SCJ zrjbU6Nal>hjQdz$)Nni+enM*#gS5sBI9}9nImppwg-B+N#;nUl&v9pR+Gi4OS6~Z8L4FOgH^JKQRp8%ab51jYg;=%MbKGwH655Y* zTyNmBMM26t-*66ZiAVI*6QYdYf(=!;c5E-ehhx?^MWXkDoG3DFWMLv^jTMnSLH>#7 zniyh-?5qNP)tYWZ!?`8~DX+$@rJ7!rogYd#)PxX+BSZYw_6O zqgn**xEg|a9BDv^A(f5sGs)(*oNz<3f52NS46qZQCO%(U>KszVqz#wC;EOtR9oQe* z@~MA8_RU$@R~>JrL1dfT8~6^_W&bem<3n5t><^3U>s7yNX%N|g`dhWtBYc9FRu!Ni z$h^vL!SAvU+KE{158`@PwsrR^I1)4}NV%@y`GyXuF-Tv$Xm>EM<^ghHHlyV~4YAhs YFR!)Dbq{rl!2kdN07*qoM6N<$g7OV#DF6Tf literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_quiz_default.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chat_quiz_default.png new file mode 100644 index 0000000000000000000000000000000000000000..c771c9f057d94f783fbbd06d240a4dd135bae466 GIT binary patch literal 867 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_ban_chat_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_ban_chat_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a992226ddf9cc50cceff25baeeb1bd1f6c91e3d3 GIT binary patch literal 1277 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_1.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5c89372048769d96c32144aaf04735bddb86d803 GIT binary patch literal 2279 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_2.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_2.png new file mode 100644 index 0000000000000000000000000000000000000000..1b43efe2464a8743ece6098dcb0edc29b83cfd46 GIT binary patch literal 2572 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 AQ~&?~ literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_4.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_4.png new file mode 100644 index 0000000000000000000000000000000000000000..9f683c0b9e4ad78e2edb566f0f2e4f3b26753c31 GIT binary patch literal 2594 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 Ef=nEAKL7v# literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_5.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_5.png new file mode 100644 index 0000000000000000000000000000000000000000..352338549ac5f02fd0f152ea844c6f68a64ed892 GIT binary patch literal 2787 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_6.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_6.png new file mode 100644 index 0000000000000000000000000000000000000000..b2a6ed8c7f642f085415537635b36d598c1271f5 GIT binary patch literal 2345 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_7.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_7.png new file mode 100644 index 0000000000000000000000000000000000000000..56be74a783e1905769c5a31a58003bd74c37af57 GIT binary patch literal 2225 zcmWlZdpuO>AIHzQPRcgQtv0u=Lu4e3C`U8Hxb87c%x3rvO8i>VR?HT^hAum*U+JP0 zg=wIN*TXYDrs7crjWBsIT-fH$cf?E0G9wP4Kx^ohsL0V3RCB3n=aj0v`l3gEFwSi^@kJN!oZz8ap-C|Om+V>r|u z3vnL`VPIU>VeSSj&>0J)V{H0omg6UQ9p=9d^IQ1|UNzuLVn5(*-_Nu~nRckx3Uspr z3fun)(@|f?0pE2PlaBd1W3a1+wF&2vZGuM;KMmqDG!Jtm)C&t`4umrMxlD}9913*D zIIbAmd6?ro!gU_yGDbt)HC#`!xhTRwxeU~w(c|ZevNx$=hT3O?n(6$WNmqHSedFq& zWYCo!bd*USfY%SOH=tZPCJMw7w&O_xe18;?CIBSjXdo7WOc9WXbo0a#65;%iWbV{u z3U%a=WJFDo(~^V`BJQ||iwjw}044-nLWJNXNnAoA!Vp+Vw}0+vXUSmCk`G|ZL0=V#bz4J`RQj_hlul*9Os=>S6^wp#`=10cvzv)($^84Jik(7qUIBDF{8T*cgy&V_o1q~C+=*{;v zEtLMOT(tF@Ayn8qyGzn1{89o(@4qKiG81nrK2P~lBzC>XVk75!=cu`@&okODn(jN& zl~FtybM!y@%}rnYB~|zLD%rHaSMNUj0P!Lm`R zwQH9gry4VxqU{WMrBe#n<*IKI$3=JucN>A;-9Au#C>}BT;NZ_r;uyP`Kpl^;Y|2YJ zg9Y1+l{<~mhDzIA7VX8gRta0Iqvoa&%TCH!;d8lU_g)uWi~QX8Un4^vbS}MLxZ!xo z=tTF8xXR{Lmm}>O-(QHoWRd=0?@6<-b15$vULMD8{t(2Gm2EC+cx`z%z;R2wxw@UVjT%xilDtTORbLXG{0l;?T@B$omwZhJ@YS_-YLGS zBKh0LE3av(f2*qF)q{(U*g!8T#s`Pixn|uq3k$1CwBD_*xa{dxoE};zIA`{3Y~TJS za>AXHYt=RhuPi1g0Zns-UVoKJ`c0$nj&)SWwf?_%QYqP}8S6=$3kc|$?aDa6&30GL zR>Gc zoRdLpTO-4Z*|*jeQvwuGRvuJ|6U#k6*a3;v4$BnrJd<)by1XCKTuG&zv8p?5VhK^g z_ws-Hwd=9*8VWx@L$*0*ZTy@xDjN!{&M}fiKgz14neSFbv0SZBU-S8#Z?A}3$$4p3j$`PucPE4;dG<_J+aeI(+bJ>&WVcpJOz$aKgZz$Q}Xl}BP15Fcp zvyJmVL*R{TdL@5-?T5LBqqwHhePbL9L)KyRk`mAe)QxF znO;#u@VO4Fi#XpFF4*Jd^I)gKXh{n zTiD0x+u_8qOCKpMzBbTWRbjoszuu|zP<37278BLf;Vt~dJ~u+p@J>bAfRf-bj2rJs2FmKBtCL;QS+{~^75EZP%H8%guPQRa8Ggc?w~?J+2Cejp>Q3+~nCoMY zKGJqaCT<>kyJrte)Ma_+(K-ri6w*m*b3YR^f{!Ej>< zPxCov_x95DHcKrtJPnkC@pThF`gl(jjlMoITes(yx&57XzSP{Za+#ho@4&SK>j!_c zPJh1ACTLfanqjc~;q84zeI@=uGRWqZWb2}P6qo3B?d7nbT=NKC@Oj#%^W|mfiPVBH z_imp5vqoWk5ar5~#zK?j0a=`k2{DxU_1L|@gGX(Q)(DNHN=i_1dC|;Cid@`(EyG{m zUZ7XS2n-H6vAkN>Q)4P=413p5H5M*QVw}%5JH08!H6p-kOstH7C7QWgD%U88kj0%d zDtY;$(6434P_IBZY1mz331!NhREKM~#kTyL`RwW0)N|sTZr6>_Pj%C;UtHK4YLfTY zb!cF``EZX*=ORk|>z_j|&**1wEBP2xy|}gi^Yj4<4(1FtFI&?CbyUufUoRBI31{El HCd&B-BlcV0 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_8.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_8.png new file mode 100644 index 0000000000000000000000000000000000000000..e9a981d69b15bb7035ebeb7fbe7c00a12b6cf1d3 GIT binary patch literal 2286 zcmXZc3se&M8UXM?)6}%gJmssRTGL#sDNV7g$Ut%R(mx?3#hTKJtC*;0Xr@S3RBUo{ zYpJxQvW?!{o3Gp+xV1^C#kE{*^FeB9W{ROU>d4&To;~L`-+bSk|C~AV{lA&xfEngs z=Vk{%kV80w7Db$?=EKI4h^18p0}x~hfk-x;C>yWF;yfNM;Nfh5fyj|WfO0r^avaWM zU;vr@aY63)JfTqwe#7b{76)Y}WVNPzWFz4ng-clue z2riwR^~k>7E7zwmT5Q|1x>Huz7g==BqlZ>NI03yaB%@HE(qCM z;IowH^ShgDejT)e)!fGl-!Jw7_pk{+=E=LQ1mO<+QR6Ss{0(vU|tsKyY za6WRt0Edkt0OfAMxB!b`O%Nq#8;T%k;trIz%OK>VBI3O=F_CamEW&a{rd$zjCd9J^ zm`H#fNS_i2h`wQjbUr5F6aB;pJRZg;Bx1ZooQGh9L3%bDOtqX-8xW8*1I zT)@T!+i@X+3lnisg1LtxKAy|}yZ`wIh#fKI=V0b0i*e~;Tv~u172}0slUW{amWxZw zyMRSfP(VRBFbZHCz!-t$j{$!iP%r|U5R3r=b)2w;HVzo$AQELoqHHk1W=?Jc;~YXH z78`+aXjlvb6cnKv1XR6<(MJ#iy%gxAp*lIxDLGmd z_sy-nx(5Pnt6bYE)tHGNyvcpgAgtDjs++UQbpo{+U#;WadbLNTv_`Z!s13-*`6C8gMb? zUFF{{B*Zlq57gJVeCmF(HZO_w4nY$n0f`{N+>gBJc`l{XY*fBj9ej$0oeH@|UB?j?Rpr)4leo zYcp$ms@ShV$;Kux^1ZcHl{`!PC7>jQcI)%yaQ~VZ2S6R`1Q}3T2?z#20oj>h9T}$)49J}PpTu>|# z6qa#?ov%`ZLgzL)-@ck?`-Lp_;69oIt(hT-|4Zhr`AI1A9XWKo=-$)k`R(f{aIqbG zXw;cBt-w@~JYiR0I^?xKNXWMP+8Z(3ChL@pw1`@K%}%OOH|~j%RNx=Ga|0G`w>Ek; z>q^mS9=xv~o&~;YU(G74WjK<*(T&F<&aETe>Zls-lB^#pk2jX;AC`uf%c~mSzTn@0 zD&6mq=XVt2DWoGY?Sox=bQ2aly-q{1&T|!?3~U^o`;lLe?LJQ~#~s?P15#%?wpfzQ z+Hv&oCT_FVWD~pniEwyl^t;&lQgMjYlj1Rc4S)@+o>T32vl_zqci*qPWvw&`d9iT^ zENeycDbqNQx-Z=kUz`=P@z|v2mGBkXoVvmAS^6ghdj`kOJ}C`5A?tTUpoWxZ5NU>2 zqv*diGi|AnyX>VcvXKpy(-u}w|E{Al@FKs5-SkLhf%N-j4aCi|SZ-?P{e`xSsSYkW zGmW)tD6YTfSkV$+c6UWEDY-Lo%%)y?-x$%`l>8$yJhbL=PF2j^g-ficTEm8o&%1&f zI+h)6*FtH6JiL3OQ%c6C3Mu_@ap<<|nJtD;Cr7Q@{)o#b;WupY?75@Nh##^p*gG*!#z)^RJ&K7z1}VpnUtCDsAw$uj%HREy_(}9Tiv90xwF;ZE0a*^Ksd@6Tr44k) zZ{%Lovl|yeuSP4$^J=~$Pn-Qbh(1y#Jo9KMUKornXmOuPyRjm{-@zeFP8LVLOu9;| z$(fuNHtTcC{DtH6%-ai$r5lz(YJ zxcA!~4*8PQ$gs$D%E5XwiCjSC-YJbu4lHR}n`Y{YjlXb$G&{&Sw(4IAU-MsD$ivbK UC%Nfi#7`Rvr!#4HLJ-OS08&JQr~m)} literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_9.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_btn_like_9.png new file mode 100644 index 0000000000000000000000000000000000000000..1c6f18b67ef92ae439e6f46e431f5b11f2bb0898 GIT binary patch literal 2293 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_doc_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_doc_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dedc79e524c24c7407a6c9a78e60dd30fd0786e7 GIT binary patch literal 1379 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 D9Tw7) literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_ppt_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_ppt_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5c7682ccb020d0dfcb0a19b1f0f3a97c1ce9e8d9 GIT binary patch literal 833 zcmeAS@N?(olHy`uVBq!ia0vp^6+k?JgBeJESsTv}q>csngt!9fw-Mg|OS6FF+en|U zalzk`!~Um*|DToqHq!fTgwN;Lzz^{OK-o7y1t2wW-$eWU`~B}ZBp33zkmO}eehISt zzaQTFb?e5L1v5TP==e}m_&vQ~CD11_B|(0{3>R77u9x8DWIC{0MBvYvV=I1bTQq&D z$NPI-8I~=zSw0L5Onja$jv*Dd-rl+CcRN6&HPKpeNx&s1=@(lrU70zjQzb=-S>)G0 z{m{@=k)~5y^&f3j-SYpnZmqc8wP`soSsVj)^5_>Vu#>Ol{!|uvOmTH><>d2gFW3gi ze?D1yz>SYldS@Gx)p^C{%v6!fm7cu8W=(}5L5HV2HAuDfiR2HycKAmCkbBhN=_T{nx3Q^DB*-L9=hz=% zATy>c>^0gF*ygDoX0R{n;PS8!>e>=~=}$Ls-TQOm)$*t(|E7l7h!n5l3Th$$CoSWKB z*#;}cS`0LKUKy-Br!Bo?s`j2GPLV&g9&DA_q<84Fm%tykf<@w*hcab%0aFlzr>mdK II;Vst08166C;$Ke literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_xls_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_chatroom_file_share_xls_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7e54e808c859f72f2e0a423172a22caecd5eec76 GIT binary patch literal 1153 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_102.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_102.png new file mode 100644 index 0000000000000000000000000000000000000000..b85168b7b1aeaac4ae2173090dcca91ece98e2fc GIT binary patch literal 6158 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 L)KsXJvkLz|$*}7J literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_103.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_103.png new file mode 100644 index 0000000000000000000000000000000000000000..9f4feb32de072611c016c0cf8cb30ae8f6ebd054 GIT binary patch literal 6824 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_104.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_104.png new file mode 100644 index 0000000000000000000000000000000000000000..07689bf70522bc480bfa7021a81277565f9fddb9 GIT binary patch literal 6740 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_106.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_106.png new file mode 100644 index 0000000000000000000000000000000000000000..0b64f9aa26e622374def77e954e9a587824b6fce GIT binary patch literal 6999 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 PA%!T(smoSKzYY8!PZ<2* literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_108.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_108.png new file mode 100644 index 0000000000000000000000000000000000000000..c841dda83fc4a186dfafe63129515bbc289e5453 GIT binary patch literal 6180 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 IC2bz|Kgq{^LjV8( literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_110.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_110.png new file mode 100644 index 0000000000000000000000000000000000000000..28212604c7367d91d5546de4a3091e2fd7da1558 GIT binary patch literal 6525 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 Ku~ObLwwEB~EQ|Daj_kr9?L9{-Ljl`|fc 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 Xjn%9$`z9^100000NkvXXu0mjfKeV&m literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_112.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_112.png new file mode 100644 index 0000000000000000000000000000000000000000..a49e991e9c1ad264b078477df08e020521df6cbd GIT binary patch literal 6744 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 R@bCWuQB~AZsFHgb_CGP=j}-s_ literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_114.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_114.png new file mode 100644 index 0000000000000000000000000000000000000000..16aff77aeac7edd1fb5be37d8c5968fdaf59c035 GIT binary patch literal 6714 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 M07*qoM6N<$g5oq^mH+?% literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_116.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_116.png new file mode 100644 index 0000000000000000000000000000000000000000..e969f5d678ca8285ec43e74b5ad423b1c21d01fa GIT binary patch literal 6336 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_117.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_117.png new file mode 100644 index 0000000000000000000000000000000000000000..dd363f5e0263b552ab5adf236b21cdbd56cc9e96 GIT binary patch literal 6905 zcmY*-bx;)k^Y>5 zJ_0q?AYC84X9p=zkVFYGAAuYVkf8^%5g?Nf)YyP(YmoflE{On?D1s_$kgX4L5Fqy- zK<|I9e@2A`sI&rE2vBVc%1uF;8ORm@^_HMS50vYHQawf^??DcrZ=Jn3HNETCOkoWsAG?WVB(7_T!Fpi#h9u zpe+XUB<^?nn{!d6*h+dT@z!Xt-zCC#$1A^i=|*YrBBj{Ag=ws`L~p%(T<4-VTN{)k z%J5B{6Lh~Rv5;O%vE1rP{8MM)EXrIGV9;;KgVE$2&htB8Z8^$z7%Or$V1d~@q6OJj zHL{Eua?H0qjv$5Gi-!1fw0V*k{LF}zK}x$u_*^D!O_R1qvhv7Dr~M8se= z+y@&Q^a+C16!1wKe6j$O=3pTl^qGRwpKtK+z_@W7A2p~(+@%qK!C)|^62w9MoDv46 zT|pU_0t^p)w*+Hm;IkAM_W&3=Fl-El?Oh27z)T?c4hK{2U|1R)b%BK-@ck)hhJ&#e zVA=~zn}IO{(5(vkw84}U=+FTTVxWixj5>kiUU1kBhIK%XKG^>bhONMa4OokFBqdR% zfP!(IyDS(u`~jv-!QLk@s0(WNz#HD!DU?~7> z7Jy$)V5b7iy#P~2V9FTm)PUtsFl_;5Y`_EpOd5ds*I+^e?EkPQA+aYV)s!fe{nt-V zJoR-94nk_a{XB90+LPv0Jw3EOP`DDm_c=Ld>F~2z%FVz;dC=9=(tJVt4`54&?rZo*4vk-&|c;!O-W|UN*jo;q<4TA+ZN~g>{^tT;eS!LSiOX znzv97RPA?Lx)&M5aj3pPU8+3Ba&gF!(sdA_)j?J0aG@024Q^8eGFJQgaRSd?3bc`|UBwjp%ksrJ;A zgfPWz4TO$jS3OqrX0^@Ro_i%n3ZX{cEF*59 zmv^dsCgbTUg6_51O~-P|6@E^CCz>=7E;d4nBka;tILR>k}`K{frnJ{c@ z(4zd-{QUe(q|XnLFs#WZcJ%TNm7yyY*c5bH%&-1rsI5?FHerm6r+*|odlwx~k`FIY z)~#ow$15<#<`kxvNnYzr7B7W*bWY=hOt#Umkh!Dd)pqoXm34F2DCc0B+t_s5BohkR z4WeVkP5F2(t83WX+xG}@{S8fwP40(S@Z7h*_wlH(f!JCc=JO(?gm{eiU1yn-5SABY zbPQb%V_h2!omBJG<$b$bmjBArTi-aB%}IE$!UUIuPzkD%*dH6)-(TL}f7n9tr3cS;fi1g!;1N@yu4i2$;hSG=rqRDPK{()B4h0k6(vZd z<{+feV;1XcWv#m{lqsAViC~ru$ziZte{Ymz_#>ja5TW78C^Wmd4nc|HZzE0-hZt!d zlCj^96Ot)rs8w08DBm)(DjXK7>F*pBPVhj=LzVqHm?$6mjhJFcJIdG{nNwv2d` z3}s!i3*`fx_dYy*-HD@Aw~nmc;m54Ha5$R^>HU(3r1>UaOoMCnvY!p7ED(!0J-|s&frz_ClpoX*WxW0*;iz4|B8~N zo~53>7~O}e9!OFuwM(;pA&K$qcKO7j_ECz_cZ`;--$40T=#3hEL}`n`BU(mE>T!bh z?6`=ePEvgOk=VC|@r zo*J~q=-S#EPJFEuB8!yedH1&JByz1MCoZlK_fY~K`^MURflF4ZGG+Gl$n3cI(_{8` zc2)j5RE^kBibeWu5oAr~W&2aTq^u`TB%&?-Dt~-k*$tQ{8T{??#?wPXc(+#N=?50E zHnPM*or?pJB!S4B@ZcKv0=TTFzdxO!rdgrlG`08ovrR|j6qZI6`tF6J~la$1!(dei12{JMw z->>q{M9ly5pCYsNQI%Fey)2Cu8gqGsR&x&#JM$*QJXK-Kaz2m=^jne@VQpGo+YRWr z`huEE;@Z*8OUQ6a&dw!D!%94zr^KHUkPmFKk$`0|dY>O1eO(SlCe3EDEXUQSsi@jM zX&0ieo>gTn3^mEO$7P0GuXrjb3^omW4bt#?aL9Q04Dnr7+T2QT3k$z;78=l&ujR*+ zQ!e1x^^Xg2mI!LtUxSs-9+@Oi^dwR=5~ztHYqXX_BLpjs53{1=nd@I2QB-t9Cx$S6 zx(@TPOA{RG?QhCaLEa#{Q8njmqpgBh_sPsn`De9Rs%|97ULXU+q^nA-vOu zVo2e+-|(4(0S<7{8a!UG<}o`6l(US|kiV5^hP zdB9wI{;r>P(O$1!d)?U0-2VV>L!UB>lgI2t`OWsC+#q8tuSmuP<6TNeRAvM*vU%&u zJe2e@e_xR<&$kfCnCR&IT%Rpy+=TPTS|!A zl;N-?@Baj>g>_K{Na35_8Pe(-?WY6FHjyPhlRIjpxGEK-ELc}u-`tHg2E)x*njo|5 zq~CRWBR5c7RS354{jwvRa-R#9z!zc`XAoXD6tJvo4QW;N*J^8eKJee8WK7)e{P9{^ z+XA|B0-T35TH5bbJelt;XcYMQ*zPr~=fO`Q6Rqyw&FdPH$5W5rv0)jkXHzd#MQ?^y zEvKxHPg#{lW@=NsPg0&dtIMy_n4m}7I`@b^fSnRQ7^xy${i?^9V)v)gYYr-ziam`$P{pVq z=pYKp;T^SsDkYpH&hxE-G8M^PBu5Z!MP8G8bZkj$aPGI|L!C^_#3eC6jS3~T$cN2;nv&@DE}4&4cga)qEyJ(cQ)!h5n2tYna;=NWt0%#U=i zaxGk_5WX?^mhUsJLg~ZN3K3Aw_YMm&MzjKV%(cN`(eKGg7uCDRQZlhUYLn?-Cf{ zT71aM%h|a$#uXf_smbDeO6yJAMRq9Uh5qf`Fz}tjfbl*G%gD(Q3YU##Mh|Zb4a;R# z;-UXQUznv4;)Ftbl_2**bp#kG z;-Q@VeH5Jfm+>LB;tzB#5g!SAV-$JBVWI4Ac%$IXs;D#y%byiuntwxlVqBwts+Na{ zdO4;$+=Hnr!!aW$%CCf&!I;CtqPRWIPy0Re3=CQHSWv6PubQ05lU8Tj&ecp!&dYdQ zJtI1-F0=3U7(!@r{KMaSOtZW&BDUVkm`OVs)J>f|hIF@gf(M_+8?{h;1?N;I9}eJA z87)O4Dp_#hhCOD%m=Z$hwrH0p=JN-LXBw6i3xrh#s*>)G?W>mafL$?iroPJL@9g?g z2QF)GK$`Q+i7!|A>T?=tyGmY6kZj*QOZN9v(s6`Ll0QP=miu+8M)PrH+OiFsg!O0{ZfhDBh5C#f_L~tQ^U@aK+LFQ86r^-|q(X=B+iN_bHCH zolqW|(sh=&xS-PM2DR&V^2?|#6(z^vTHfBLY;ta3c7 zgt!gAhH|mDcguVIYItC3E01y7g_YSFJexbyD0{PTlZo;~#b;xU16iu6CQ~oE_)nOd zGU(xjOu5iVXNmlQj6l;U+D9%+KnVmUU5PFQ7YBCXqbF?&BsdRXGu> zbkuA(zJVr`ttU3XHGJT z(6)Xfm5kwW^~U@1!T$(SCQFrs3SPOCMjhEfSp=_dE?=|qPMma6q#ecbeP|BvD>Eb- z<#bQg6zA7=!;0|Y$$HpXQqxwxgOJBFv|I}#^!))_%Il7kun~=Lgj$H7uzpNWrrJ-& zB{HtI_yS+m;nd>R3cMK>zQQCKZy%c#DeyItPQJfZqHP=d$hS!F=Zsm>sv$xh;VVTl zEL3_?lU%#FsC?UQ`EA5$81GR9iT_KQ*aZete1(Y50Y5zUuxThjG&%^%@X@9Y5MdUBb3`wGQ`m!p;>c}%kb}vZnI!|v+cId$)MIrj)C}$*5`Gr)D(}b z^G6}6(JW9-Pk(+R_;rWkEUi37pgjJ8qeRLj-{U-zqiJT(jc}4(GX^)(tmx=y`N*eV zu2PjAxly+*axU@a8vL@8{U};moRKkM+t7c69u-PgBZ~74cpei{U~qi$h9b35`{lsB zCe)EENpL^E>?@G_{!`EIfG<-H&9@@7kN-3X+wpZgf2!0nVRRNl?sV>{h!vVX;PMQ3tXuBig z>8Sp=t8ZRCyeJvsf~2w{IhQx&25vO9)p*1E$-e!R^=Tq1Ud~M2^i5-;wvFYuFze?t zb$vlM-CJ{R3K-l@N-XpG4D&#eH8mRL{p7A-LaFX2X+zQ(?0pSJx>Sv9<&n6$79mCJ zU1s|tXqTST8aMHmwWbfH9%Q_DkGk$`E3S>X6(>p%JCitY*GUcUsY8aWPt~jU2&$}1?lAT3XJd&I z8FLK!63sm{r{%}T8ef!OJ`r5lLsJ*~&ZmBTM79^4i_e)UZR|lzA8nC9NO1D3wVb=M zGr4CUR~O-Yrlj1MSDqw1*h30Gd^e~aohEfogZ8Mo{OT~cNp z={_0!6#HE-!NoQwGm3e$&YNVyqK~C~K!yL{zWy0rOi66yBV#WGKrMceG=~$;q=D->>(` zR2ynVPfHVMXqn_j3@%=xM`aXEdg=$AUtBpmGpcK=bv-#-`DqxG&iayIS4_;d-=g_M zz61GhuZnZXOG!0-OFy-J>w+vV#EV6|V7o0iaiokUc(H-ymA&~!KY1rVr>tn6Lc`jD ztg7`cBV&P=a=T3OiE^->c4r;?`Q*$Lu3sCS3U+eL)X$xnhsMxCO_56Ga$A`TJ_lLz zuKE-5l5bNz_%*M627mI<{D*5o>suPEI%@K8#m& zv$0SnZinaaeJg9zBe@4((EUdoO7@4X-Y#El2mUWN=|{H-6{#9YnzCBa%#nszNjvdO zKKe$HM*FwdtVfJg!%;Tfngjv7d~Dg80=^Luki-;&cSO+NzlLkIH}=?K$LxyELPLd^ z?y=KaMi14N8@fpukhwX?vLd9$E=`_sE*#@CE)$?)c|ASe5D=$I$Ggn=`r8-gH?`?M ztPUFqlN+Sd{l!=|=$EuWLn>VP=hyA&_^|w~1NYq}-iU*_+2S#NcAD(J`?+K$xQQ0G zzmbYh2!?i1U-FAme-@=7BGqujEh=*}e0yMSX4c+tF~)_PV37YIPGU1<^Ex5Oye1)3 zPmPCy3(wEre@!E1Cl~vx=U0L`kJ&7Xl@KQ85U65q_<2QZ-}#2!T#eByD5GpHqai#}T)2X!b~HK1-!jsxWqW;Jk;ms*tC^V0NPR?g z%CEi)=Jz>t2|u?8$IJKwBTnl@Yk3)L+SS{o7k+*<`qO{o7j|OH?Wtogg(`C2;$w(X z@I%QNuLz_}&6vOLg$4ova~7WDcSfcn{SGDmQaX!x&M3${J`_rQt05{}tn(VJRAFh= zvO^n9LH-z*OuR87ch6u)$ry268+Uq1E;A!*zup#pex4<_z*r2IqVpY_yZNndT0m?I z;oj6Jx%lPJ#G!>!B|9gvQ&S+NiQBiyX-;Hd8f9P!P;$R@3UDKn%oAMWAx!CWXloNL zARs(ul5My(_M?vzwPxA%Phz_=^I5Fv{aFnYXj|9)+sHmQ?74sM=v4Q^lW_Kw$bLno zaHa4|Yr4PHch*g2CS<4|VFH<%*9v5qfs`%W+#j!w`1^FHSI2cfn1%;C+{4Qc!Hu*c zXeYUgKUf~k3_iN&UNw!Mr%+%?ljSZKRF@;t_?k6=2Dwi7Ux=jxQuV!@tL2-!>uQnK zA8Td>0V_}Zk6?>=ILz!nNW3F0schi6B9@Dj0R$2RE-j1e+eSp=JjfDd=pM6gSmbiY z_(c0f?0;8QM`vd(YBKdAHqA|cwU;irAapyRYCtkB#n;i1Euef4v{#*e) zJw?ss{(rSI9^2PMdsJxjyPZ+(g`2Mv_vl4+Vm~Xdz6)x95m@OtPg83!JR`Pp^{eqk zN%iR5i?wTSBLily&_&wl&v*pgq`?b~>zUH$bB&+{vi<+aweXg~Gu2#WqG(_E-@hKBuA-w{t!NYWf5#|$PXGV_ literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_118.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_118.png new file mode 100644 index 0000000000000000000000000000000000000000..f14a0e380f60db2f9e9562ccb90171c5b3ead37c GIT binary patch literal 6957 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_120.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_120.png new file mode 100644 index 0000000000000000000000000000000000000000..6541791b5de06be6f58fb79e36514fa7cb18a417 GIT binary patch literal 6463 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_123.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_123.png new file mode 100644 index 0000000000000000000000000000000000000000..0221684536fdd4ccc54984c6739a2abe4371258a GIT binary patch literal 6500 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 B$|?W= literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_124.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_124.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd40097077969e4301498582598c8285b86798f GIT binary patch literal 4149 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_125.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_125.png new file mode 100644 index 0000000000000000000000000000000000000000..3cdc9a660c4b89862678d4f84068b159fa588f10 GIT binary patch literal 3879 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 LEmfkjiSPdb-{nQg literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_127.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_127.png new file mode 100644 index 0000000000000000000000000000000000000000..fea51479b247c465147508b729fdf5ad09951007 GIT binary patch literal 5039 zcmYjVWl$8}*QQx|#T98m3`)8?C4>c0kVcSJ77-+WuyiRBBHbNJER8hMN(o4JcZb04 z{o{vs=AAR=o)2fvnP;BonLBrGm^NI6f|Q;V2M32jO;t(frbhis2>#7Elt3MRQwVJ2 zHRW+|(2-=<=7cyn_&C}cFO|V?I%Y5jbcTUePtf8CI*{0s7ogq|ll=tLBfwxhK)(SU zzM$O~bVY!L?;uAQo6QLZ5@2;{5$ThiJ8|Qz-DrTR%A@fG-yYHPJhts z4O)Fct2d~!2Q6Np+zb@!fg)W{pb1dgm?TOtivle^0HqH~!v3}LR6$Q9XbSoV74-_# zB0wP=6g~ybUZCYaP-_eFG(he%P^1a6l|ar7P9HE+45kagbiqG_H%JPUZw7COIxa+l z^-i$a1ICL%^*ii*14zGfROkb0?XTkquajZeda!{@Z+5`6!5#YNs zNW?wN@jNQ>1G7zsdETcrU#^Es=Jg-mP>M|^U2%|Fwi91@FMnJTc#!cCo5_Za!@;IA zf`NGOD;CT)oS;K@Bh1&mG#4!em#l>kQk}v2z@nwVnzPb|k2ZF^60G)ZhZ7s0 z>cMg=$b^Eq+JEM0^kCfw?-c+5_fqS`A>n3Cz`lx$j`U`RW@E%-S1vBe}7Q4*bP6_Ucj} zvp;hzarW%$>i9aT`t+i$w{mj%sci<=xh?XrG_qmk!gsCPN$T9?EFX@0#y`)rix|){ zz5Pt@^32|X&|2n-4r|0Fh!|ZZQ{sItE^=~yetz=Q(GG|7sRacN4%LyGlKe~esofNk zmqz1>-Cpp=BX%}M_#Q;4Z4_hM1< z2i$Ot7$?4j0DMY)^3F$X+R3C*DGA6MPoOZCJHY z(;!zn?{npyfo%JJcXKECWMe;>b-t!Z9C4CToq zto*6Oh^PU}z9_I>q}S>4CB89$o&^TRS3%=Iq@ zK|x2BrsEoi_wR?cPqXfs+Xkqb&a@9jwGRaF9Z@nfN`=0B^(q7_M$f>&6hWy{+pvB} zHCJKV#^^_5d_1;pBX%?V!iiJe7`GE`YZK1Ra{l^reAHVTMicSW0SQpX)8Gb|Ba^wV zOiUza5fmcJvHT3fJ~Dcy<(r>65b$TU)+AnbDEzH}J2}fprb`W~uYK)ho=oin$BfQ< zeJgEp>ZJi}n+1yoe+Kb>RKjg6{x4OWy0B@|^jKz*_JzSL!s%08{0zhqP+ zB%5*Po|oq%1}KS2rod7;55nJRWkx?F9C^SszDnqFg$lI7+jP1MCsi@e3suZZDXl}( z7!dxZOa`Q8T{bl*a_(x9rrnuE_2 zN_KU>xlW8KL+clh-AE?4`Nd9dP+E12mDX^xiyO0?8^-bx7c}fmY+zymIh0NGP^`~@ zMnw6lr^EvXGjh**t}~Ny>BXJMbQ^S*nTHXx-1)UkzTzZw$@9<5N{6yA3`|j*%c;oG zW%_6AKvhnDReM5{vXHxrpNK9?UbM*B4Gr+J$|Z9Aba+O?YP3dq;yCHIWH}-Pr4W_M zO&myA^niLYXx5)Nnn?{gE*n3pL;ZqB5%u}>28Tm3YHw+KvRgzlk5*`WJupBiH9=Wk zj>@~L+Zv}$z;6G{Ld+<8SR@Q}ZewjB02!aTEDM{Dm0PN%ThLf7>dElg@HW z>5V4Qh76q{TwLQfgMO|GWIOxQ#ed?;f1Ol_crMo(fIZA+G`Fr_&>64aajJK!WTdO29}KQMWuXeZC+2~JWSEJQoywJz_hSYp zM$#aOK+ghogiI;zp9{^euQTkaAWjh7Ws*sYXsHInrAJZz#T^mKP472D45jo$PXYJQm%` zHyOI#ANrjL&s-~G>t_!~E4wMnIEo?_l6Iyl$BK)kgp;?6-HH)oCDkbt*BfiurY)eX`{R!=3$DyG^qKy&ig-qU&dr_8V%mR#9;N7nSYe|Jr_GA{dTX1olxvHnz(5Js5l zTLWG%b)ngPx5;PHX{F%^QI9^@Sn33%IW|+HKA+U8zL8{3!D3F4w`=j;3R<>wLR8xR zP)KT8)%W_2F0;FNF$+?-F;}m9m!7af^qZR}=TF0Oz1|N$WC(o&M~6OrPtsPSVA?+` zZun_s*N}|o5G5u2xM!Z_DoI+0MBmpp9Hu)xJH&x$^eZqpl6qC*EAL}YsSJtADpCoz zUug~}CC~9OJ3^J|QTwp?)X2x#-$txOH9O|NvzxtSK$V!73^FNFDjyMCDpIn@Iz!-g z^HsCU9J0m%zCNBkOPgHw9rXoec3;(Xzv0?7)Vdh1I^w} zj@48jh@VUpkC`z4Ttl$4Ht69Z&k@?>A)|$T@cNlCO>Dq>gOR+n9!C2O6Q-@MntQu3 zwYq8$2x(DCqw*)EmnSj>;(4z_>^WmYXItpDinEM%(bGTG>CX^>ccY7*28zQD@rU$w zpi*)V9hlV=gil6vu-=tN^5@Zh+^;cFx+6S zrZ~s-*`1ky5N=$}P{j?j7J-&(oCA!V+PHGe0yl)3WbFJGTrI{bGPjJzotoq-Z_Man zp(baD?pU>VOn!-Gk!LBvd_co}dx$te^!c|q#C$%hNFBSEi`8bAJ$c5MW5H~-)qYo2 zg*#sIP*t9#H03Jrxovu?Kjnk6{PTBEs4HsW(Hc0bSLL_|F>JZsuT~cITRRF zqM5~=A3~@)#9(2To^9Q|p#vtv4N~>xu})Xcat2v8^2=SfhUE&CNYB}c=+}j~V#0IC z;re6>@zVY}!I3>8{pCS#-qg7ySfR^f`DuA_qQhQJ&BAW6S)3}$e$}}LTZi72{w6Pf z_n>a{cdS~NO1nKo#8S8;_X}C#!cid22>p^y$RAR!E!d|ocvkEd@T58pSAUmNNEvIX z%^0W*jo+3O{BW|LCHZaNx7q)-Xw7FPWA7)WNN%v=1KOn6>h4i8C;d$DNFkq z=$_a`OF5a=~)Xc_DG0?XtdwZ)w#2iva8Ewp&yVsPcc!FPjBf|N*!dmXtETAq1#|TLX|Z| zo(sp`svovysF_SbpKK;jC$-9j+F5Au^QoQ%O2C%iMRpngz-6eqC2cRzWx+35v;l?O zJ)5v)lnL4m%WU9x5{_kI-DJ(y9v0~kWP}v6Q`)g~Gsp0><129 z4U%X@bb=%~T{aN~Rfw)9HVr4cRRJp((g!h8dPu}hEeMB5{+YyUBw`aY{w43R@n&$M zF`AZ_UpO}OsW*8~(Q9%&B^F|Mffs!syY?V%5F`Iu6nh4cr=-&|h!ph|d>R4H9|`hQ4E$XkVJd&?Nh%2fTl zaU)BICDm=W_8fB-_UsW;MsIrI`$Fy2LQM1;e-GCAqo5($6wjxbh@K{lL0KeHGNERQ zxiJAQP0c-+7)aWc?{A#YdtGF)H z=M}gZx4!TvwNp*FN!eAXNlNk*Ix#3cv1C_f?(q=0=U15+;ceo*KKzY8>6Rbam6_4{ zYZv_zf+K%2l z#g`}Uhtq{#pk&_exW&&!5fA0_V3b`$hD`e)AA5e$ey^gqmFDNiYAh_IMKmq;hC#{d zkJVQ5v7J!B-}aZhZ{@C7`?aiY=z_zjv;y{ z=#^RD^HEAhX74gs*qP~m8Y>GOExlZjkjrZqSc8Csgal>8XD3C{juPOpH)F+h^w($d zu@~~-XS_A8-?*M=_}(c!$8ih|Z9CT2);#hzy#=i2z7jEgwX|vDUQ_z7Z8AsX@HCi+ zoa@mr_#Mtgk1zj*BOueQJ5jJIkZ;HjN*R&G_Fx63Mn@mK1;@NP#Eh>Ix{MrQFp*a7 zf%m)~YB&eJ%d~tiOhLjRK)A0$!+iLfPvGf?#_Cdc3}A4yK-Q z!HtI&Qh_Ao^z;gZ9YTCAILY##dWOWVnXf){zv#RwGfS9{e?+#Y@9K*5I($=x-3a03 zZ^Gwr_8=zSevjX@6yyr^wwem2`z=gE%T%4HAm%q5V8tt2zZZ0dVTzxP-WT;NYpSnp zYRbMK*1EpX&3kO>b@bA8(J{`3)H_~EGaoKJdD#A9eQMgvD<1iHo_CH0#@*=ip`xiJ zJG-Unf-uWjOZwy9(o19G85t7nOk+6Eu>dhsu z7eg@ba4~YS5(}1ISCf+Qyv9<*EIm^dTIsvHVv>`RlhdEFvY4qpn>${p| zNIn|$xr}>DM!H7uvizj-XBkL-w)fxe&g7R$rJSpfaUUl+BAq5F~S*tmL37Ec2+CV+aX%)Re)BiIaQKybRd^#i2r hn&1BgcE%42aX4vmTZ^t|xcOzkQB#I1l`6dU{~urUO4k4Y literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_128.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_128.png new file mode 100644 index 0000000000000000000000000000000000000000..d11fb554bb2c7584e31c4e261d589a6a0f58a26d GIT binary patch literal 7782 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_129.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_129.png new file mode 100644 index 0000000000000000000000000000000000000000..398ee4c6e53d54522e3ad0441bece863120b9797 GIT binary patch literal 7182 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_133.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_133.png new file mode 100644 index 0000000000000000000000000000000000000000..4e04ee8f53896195b3b9ee2539ae15e994765c38 GIT binary patch literal 4969 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 O2u#aJvsv9a;r{@m@Zt{u literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_134.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_134.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6a575ca14ee61cb46968afe550673be5c56e6c GIT binary patch literal 4454 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_137.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_137.png new file mode 100644 index 0000000000000000000000000000000000000000..7e5651a80a2bd8aee96ba0bd78c82412dd41bcb0 GIT binary patch literal 4159 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 JPDHLkV1hxcL~#HB literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_138.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_face_138.png new file mode 100644 index 0000000000000000000000000000000000000000..4afe4e850c1aab2320ab6ec5872c25a5c5eae0c6 GIT binary patch literal 3644 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_0.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_0.png new file mode 100644 index 0000000000000000000000000000000000000000..a982831c8ccd282d35a9c69b6cca333eb1cfe3e4 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyApt%iu0Z-fwShsr%`~97(j`HD z!3<{Cg(m)bd;j+4)v?Z2a=e_+F78}5wI?US$ADv>`+uOa)t)YnAr`04PV(eyQ4ny= z3~>{D{__6+dAx2u3lgtN-){=IqP*~v;`+r?4=da*+JDS7_SO3xH@TZQnofMzwh4)R z*xY{Jx^-VaOZ@Qwsos~bC7$tBz9?4T>>`oa!Plh5maMeKZV{_^cYm&Li*RrCFGE8! z*}Mg8>Yg(kb8kd<{WRBNym#+@n{&#eR~iep7)CK}QI^cP`(V*Z-IJGdxdLYIj$G2!vEak-ar*29fUsFYU2AgT%|7%sIw;3)UI>GpCm&Pl}0wuj2FC=!SKb#@E&T0O<1~r>s({^5) zkrSkOxveKW;*Fz=E?3!&++^=Sk%)^$bka-f45JYD@<);T3K F0RVj>%D(^r literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_100.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_100.png new file mode 100644 index 0000000000000000000000000000000000000000..5ca2c4063d41a45908d569845101abd27609ccb9 GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyr2#%6u0Z-f7}#Iza=1Db$h1A* zX?MN@$gn%#36TP^&vgJ1oQuqGxX|rzvBTj)m)(UfWO3)~y~tb$+ZJp{&BC*SK#NsN zg8YIRZdjP{{JOhs(j-CNcW<6OxVUE3vYwon2p=~`10`u;F3zo6;$rVTYOV%qSnlcK z7-Dhy?8W0kO%4LC7tI%YoU@!+`Tu{Xn21L6gJZnu*F(!M-@P$6=)29{BWjzaXWW=j zzPLu&!uMdN@{4=tB8va8wAZptUoG@yvlmC|*}5>xEzjCFy>Ji>P@3JuGl?;Tv-js_ z9<_k0S5yLCtXnPKa3vyHaoGmLO{~c}kxg~2j!%Oleq7=(s`2{C;dwEkH8(>hqpi0z oS88J5tw-!ad+nQU%l`h%q~j_b&Ah}e9_VBSPgg&ebxsLQ05H1JmH+?% literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_20.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_20.png new file mode 100644 index 0000000000000000000000000000000000000000..83cc92c7388d45de5e9c375458fe53c2e1e30ad5 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dynE^f_u0Z-falr0e2SnlhAFqK7 zyYnEf-T6+4pu>f3hYMX0HX3PruH)YK*QJrOqCqYw3GxeO;5EB-ZKBYx&8wrWxZk~b zcJJQBoy(^7^HPrvY3yn*ZNwne{YU%!1zYPEslr_NtSo~P!W=r@?S zl<9k4qovlSR-T(4yA7F(*JM9y2#M0>{BZNtxUH`eV2w$FBMO YK~u%gK3KV@4(M_QPgg&ebxsLQ01VgGp#T5? literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_30.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_30.png new file mode 100644 index 0000000000000000000000000000000000000000..e8d1dddabd00b49ffeb8ca9320e6fcc6a93e8995 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dynE^f_u0Z-fD){~XFRB2DXLqgx zM4s;ilOQ$(Ktv#HhYQ_6hQoy}s2q&4J=c+WbMacm8>>MsC<*clX5hYIc6XxCuhq_0 zyzkyTyLWNt)=kT%_TztUc9o}#V~EA+vlmYaH5rJwTvT(IF{M&2 z`u~4r(~gjdTzPj2!YZfk&W`a5I8rG1V9M#K-NLr!wr6DWWF&O&c+QBpbMrcn&TD}c zzdbl~&d&|`ez8~RWb$N(Ps>;}olEX7a6S>jon;#M_2>F4Ia|egzT_mFc=tVrA*Wy2 zMAfy$S0%zpUDk>*?BMUr8QDTh?zbhro}AR=_@pYPGLL2R&X1n^XMSYneA=&YzR*_R YLPPxcU1t4##fD36!=w-vK5;Y&dYZ&<$ieTX`g-u?n90jbq#fBCLmkrIwt(Rj0X{=rCY zC-zj%9QDHwQ@A~sG0O%=K9=7$>(W!Mr`1uvV_KWnEuOk6G6S3j3^P6kzonZ0}S?B2bLJGX9HHnqPeC&tIk(ST)glJmy3K;;`eT^vI!PMlA~G z;Pz$xgNqVv&DF^g73_5%ZrNq;sAF#5_`|K}jNN~p<%0Wm8u874;IPbc-(0U7d;as@ z*>bo%Q08Evp`3o7z|mb7HciuAAsUu_YtF?lK2L3?7G9VZt?9X0$5&;xaKMy}T7{7U p)7}ef-h6(+m#L0xn)k2goU!Mn{I^|aI1h9?gQu&X%Q~loCIE7A-(CO! literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_60.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_60.png new file mode 100644 index 0000000000000000000000000000000000000000..5c2e7cceee87d6cc67c2f173555c35659b8f1bbd GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy`2jv5u0Z-f4E+56_ultcFdjN> zcdi2{WOu$3OoG@D01<((9WHb`TC&K^xvz)5u8zlP0*{#-wMqO46RXwU7qI%@@sCrRsOZeDmudFkWNTP~ED1;Eb+nwux zh}xa+1TyT-L%Co!NCW~LE_6Fw=z{S;^v(aDY{7c(eSdwO^T1r7l}aT+e!&bpx2~CS z2>x0$opa1{A@@b@=M?=QUXBHHuU%&6RazSH#B_JETcIs2wWJ-Dsi{5Ji*(=ywA-II*x zOq+c26U%cKaVxW;wpoR@E{H~-<dBY(=zI<-3TN_}wqjCB+lJeUQ!gFv il~;MNK4EK8MI29)WX<2Q#gBomX7F_Nb6Mw<&;$Vas^9_u literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_80.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_audio_volume_value_80.png new file mode 100644 index 0000000000000000000000000000000000000000..a570ba27ceffc8fb6394716b848925bf5a02308a GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy`2jv5u0Z-f4BYzm;>-WvFdhnR zcdi4%w>#gNd22C{ZFe3a0$1vAp&Q6{xX=X`fiP^r+B0u1_MB|?9B8FdNswPK!wsH^ zW-Wv5H==h zcdo~Ofy1rf152U5TN?d3qfOi`eHiX}mQ z!3;b%%!GbDp5$z0#QyHhy*n3oZr!wI)v~GmJvp&45k5-NKb(#;0u`_Fba4!^IDPh_ zr%;oF2=j%K(`(Lr=K1)qJS1R6)~dqCZQH&7<^;)4f4pScR4a>6+i+38FQ3Et_ZDck zT-bHqn%OGp-raSP0_96Lq)eT1>Wu1YITL}L?+k460j?z%b6ffJlviZka`?G(dc#>M zt^Q@~JR9F1KWshoOF=+DSM8*fMrG$qMH`BAyw2`+^GsX&dYh!Cdj`ktC#SZsep#lb m{yFUsze>Y?F3+adm5g5$CEA^5Jr4uAn!(f6&t;ucLK6VsE6)D_ literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_button_to_close.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_button_to_close.png new file mode 100644 index 0000000000000000000000000000000000000000..2c307518ec002ad7682f1cc9a935c1ca6cee63b6 GIT binary patch literal 854 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAk#>Hwb*S0Mersp)@mG6L13&Y#w{uV>DGJ#p&Wu06je zP5#~0{qfzWPtRU`di?y$rK>;Z&HpuR#-GNtXlKCum4|p z#n;2fzU@8mbMexDd3oPAZvIzTIGOo{KhU{SB|(0{3@kt2Tq@?;ko@8O^ZRFZPU_5! z4t26IR+8Gt^ZV>e1_mYvPZ!6Kh{H>+cIP!2h#dQP*!ROao(r|Q(;tdFzmj6r`~H8* z>1`<`0UIyeXP)!NfA*Fu2Rio5%rI0`StD2((ytUWiFVjFG@GLv0r_4{~z7>w|?O! z1)V*NOMc}2j?9^n5W6Qvh;L=1qoB&V+g}bW;k)^it+T`C$`j4(DNn!Z^`~t$G^~Cx zV{ww3-oKqoeLM?S&D+KsxGAmc8mEg{uY!f_j7`^NS(G;^bVPC=xAhX6sj>DI_mRw5 zbI(T#=0}_rQ~kVJbn|mZ0k-B34;q>`b8>Jvc3$v^KKkST|C!C5-*kBS{IAE|TPFYh z>$@cvoEwY9_dUDB(|c}vqT49PaO2x8I%lescEjA5{i1WCwVyoswfV`l zT{|Xt%ay6=8ntYQ%RbU@SVMOc@6G2@d$#9w&O78D;CWfA_s8Ys(_bZJ&Um?dlEOFp zBW0Vf?wl`WuBQ39s762Rs#lKF*8jbiejJ?Lk)`+E;bsN=95nX!5F!lOMhQ=Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91NT34%1ONa40RR91NB{r;0FW_8?*IS^b4f%&RCodHTnlVeRT}=!z0;X? z+G#EHMR9S9GzwK)5>ashiw`tbi6*|H2BXAX63MzTD$#6Q)-}7XuGwhtnV?w$n-wrV zF)0wKMMV*$#e(cZh_#l=&Q%$HK!l11HhF&#ly4b>Z#|0l zz`_e2Y*~$sqjaucnA;kzKk!W1V3^f$EwTWB&F7rw+tJAw>jmJun4*5-_wX$rRz2Eb zN1hq4D*)9Vc_Ta09jsFnehb(5A~eDkJt!AD7i-iswplGK-qKKU?~s|pR_{A%_>zuw zxx?-4%Q&zVXnV0$W9-qhAOrr2ue^NS*0N;-_GF#nb_AeWzQY5}dzNcF@>}3gcuIT* zY7Dv+roI5x7q4w#i^Fy;uno}S=09H=(bT^H=jYos#!-I84yj7yu^rWqe_=!sd`CpT5y7Lw5=1<>^e*PPQoH1H~pGZ)DyO+OFYpO>Bc zn-Ax#{LZRw%K+6j{cVA!h1a4Yid`mC=~EQX@`jp+Ke1x8VukpM=4Wrzcz6TyOg3=H z%>da>K3MTt7@*p{Pv6ZWkyr37m1RZ2grY^;$p`X9)Gnb%j8NCXaWCK#wbv;+&Qx{9 z$JLL#Zzj+bAbrfC$7(Y793vDMj3~@=m)V$<@)4uAl|CT<)W9LY&?oYZd^Ex@)|M0? zigTi`@<}-$$NV$92FOS9H5p-2fb<~HfjB4N$$`q8QYiHnB(ovI?fjysuf}E=jzRkL zA)>r(%p%r0GrJh>nQ}SQ_-8=uS7;sXgx5NELi6DFVnWhLrK;M^M$?jU0MW!#Yude4 zc5cORW#f*im%{CZ^FTFlFoJC_9{UKk^&T*|o53cWyD2r7EEzk&js3W%EW=s3EI0)o zKm2L>O>k!ta7YP(_CU#%P?dA`DV-CcMw4yweM~tGAX?ASmn_B*iTvwjS@4HxOQBl8 zaRTX)l4~JH@rj5|8x8qR7$hn@4IoKY$mL70#N9iYJw+<^6QF_EYRC$$k#(s6X{k-l+l6QF_7ULM(@1Eg_| zn|kskIMNG!;bAEOTY8$M_}pfSZge6*t8woaw{! z6E>=POW}o)NO)WXY1N47-YFOzmkY7cX4UJ*cfzLbJwo&uBJ#C$?%k@;K>{ZX_;ldE z!eX9k{{Y_YX%eQ-6d_@w&?yTi3^+U#gdalPLZUjtJwkMuCL(MUI)dVqA&vcFz38gI zY^PMZDu=Ma9)#y}94hsFEii(xo0Yo!3t@`KdgN^;*XjF&jWT+8$r0I|BLnbJ??F>p ze$@;27cDfU%QyiZ?4mfx(VueDiLZbb#mvfryh^ylKhumX)Aw@;pxCiDM~wL~)B}zE z{}z(WhpI*r@GCSl{D6YS=(uRRE# zJ+>9roP8%o&*lsC*{TPg!0n^wI_lxGf&ax77h^bZKR$-@ax1_y+8V~kc>9Ti@Mh1K zaD2r1k%F*MXFX7-;3u!(Lal1Bk?S{3--T6&uGjjQq1#w-H6;7E%#H#~DDMgeuBPmRZ?VX-| z@cgmuLNkA>3TiM+$W!9G$5z>au!yBu=>U-gN-44|$tJ`0-f!UPqg!B@i!6{>Q#Q?4 zV2vSxIuVOFK$LHVdxzHdZW08`R6id$3=g%v32lPw*&;gVjn*-Yd3REU1*2F*nd1Oa zG8*MuNy)UyL`U-;YTF16z5lT(Daua4W1n_XN)};|n3xv_h@??68pdAEMq7erp439{ z+_8F$ptnI!cu&r)*lfjdOL=w=aXJa;4Bu3^sbDT#fm0NEeWxnhaKL}_1&DGyDUA`?oL^`$wj~p-edJ@ReAc7@k+qcLNokDu>X$!4 zmI=2-bW%DL`ev5Lni3$=L-|xVvt5bRv`uD3{If}etEuWrvs^LKVG0ltQD&aPVHH+? z3LtUvMI_shd^dc}(+#7dr)FxAH3*aZxnCo}>1xBrih7PHIAoS3fQaGemKJUqAOh*< z^kD&^F^E7(EHv_$`YM(J23U#h6S7X9ra)WG-d4$Mm+C=@!p?l$BoU1y^)sKxNdnB+ z<})8y8jDDh|Id7)D+w@0&H6{)FjPc+y6vqAEKl?ML2>fTFfr`9`&? frM+r0eJ1e#6O@OKeAptz00000NkvXXu0mjf*80ev literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_fullscreen_exit_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_fullscreen_exit_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..01e4be3611e9e741da8575baa11f5b716e773508 GIT binary patch literal 2138 zcmV-g2&MOlP)Px-6iGxuRCr$Pom*^FMHt8b+gib(f*3E*s!dT!P!ljFc57*EW2&IkUaX3Vm(UVl zeN-QO@WJStJ{l+yO+>A|SQM}!#g^KwFG8XwEs-LnfM`Tfi9+qx{MS9?bi2Ff%sDf2 zwtHrh=A_v(x9>MIXXcx4zKI}r!<7J*0$65yE&)&kfWPs{KZfb#-=*a90)XEEoVPvs zTh4_@4wZ;PT>)Ta^6z@dW&0Jt>Ez!T06769XaE#?8GzLQZUUgIJhK4K0yqj_B1jmz zDr|4e%=4C{&~F1!D7mGJCN~4%L=whH0EDA0=mb!ZZ0+j-T&JyuVj2Ag;Bc~6#Kod| zds_zp3Z6sEIsn&tE2j2Xe*id=>=jBus0MH|fGPmXwTn{U$C0z>NSN2EcJYOo88n{Q!RUQ)#~dN&wUY zxWZ2%7I55u0rUfy@>&N!0B#5H0055tVGjHjdAOqdjh`+Lc@_L0Df>E4e^-o)Pea;_)O%(ECPU2&885}cASKs`a5SwJ#MF{ zZUJz(c`QWpd{LpNzRz{SrvMxmYisX`Y2I{+h2b#?=Qx*g8-O%Rs=*9cj4 zM@|5^x_vSa6>H+6^cI5(ypOVJQJnx#tC=q+W{z9Q&Uq}jja@|6E06l?Etvy6hUJB?G#|wa&nVISO`ubM~1_ro<_Z=!LE0+xq55FFXM1;>G zDCz;M(-%CKU;&7#GAZ-|V9%aCy$uZw`+Q5@mOximSABDHbBk!23IWi>F=hea;!BAM zxd?#S+1Z(%o}S*;*4F-b+;KNgNR|Z!1?cVV-MDGfrbh}33$4R_j%g?az%y%I1i7?e1V!sr>OCGJU%uycCw?RT7V7HimT%dzWlec`d2vxuks}CM8rcjL zdY1rbP)lnE6ZA`GI4yZ&ck$VN*kCkUVs z08I`}&@X|rmi}MK6jXnG7F>?!2!PYXs~23+^P|9j5dd{S`F5glq2Rel0PV)sKQLZ# z10XQjCo)a|Fhfvq5E4U>`3MIGAn_4arU?zMUJEAY#59yAU+AsM1pN|7EX0f|Lcidx z922Stql^mk(5*spsZ%Iy1Pfw4JkDuDTd-s?uONdM|rG-RW zTicy$*RG}KM#t0sI<_QPR$2?lc9fcsfykyj%~AI5-TQfCW8*#*oARBVo%KykO^qVv zDLOXgDW{w=OX=?J?rLdi;So=1p|7uR%zL6>!9miB_ zYinPgoSe*hOjW0OdLRchcz)p6v14xq0YKw9VSDv59?;-R+Vw&q1d#EF5&>vGq!&T} zSr6%HKc*To0FK90*$cED)D9T{$Aj7gpw(4Dhyb{DRiJE2nr;#vA^@(Pby&SXi@TbT z01$RpLkPxUlkmDZV+3J`O;$?AWto2no?VtPYvZ)f9{}G@`8^{Jym8*`4uTTr-B#AdeSLNaO5N96S(^(S(nHX4 zfrFK`R)w9ro*(#I+O9CMLok>4{C`J)_Dg*1!;!hhO7PwodtY@s4b9fS%|&iLMn4$< ztSPFw%FqJ{SpX~*c0~xTI^oqMqi*hpal=C<04qOpovj)Wszz&c%b61Zr1POoqS{Rn`gvc~#M8R`IFMLI&C#iBwPDQyKjG|h%$Z;0)V~T zGzey|APgQB*Hs?c=budqovrUfv;)r2v-Mo=X7G*(!hI({j8z4S;`a$$VY_KnJkrZO_13dA7>`2TsM^Z)1IC QjQ{`u07*qoM6N<$g4spMRsaA1 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_camera_closed_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_camera_closed_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a75af277e3012f0fb1c26348681562ddf5ee8ea6 GIT binary patch literal 1566 zcmZ`(`#aMM82^sdkxQl{*Aby1a#`-VjjXS0F5Pg9R-00fQ_DE|p4t(bI!YwuT6B&} zXVl7$OK283HpwH!#%zlnC9@IR5uNo1^m(55{XC!NeV@+{pZ9s*yo2FbEp;Px006YW z1A$RWuK8AKo0a|gE26!UV5BH42A~Zg=ad3Y!hkVqNR0sTEB|eH%{^VV`3hIN!w6}M4~adc-QH~IV~OlEolJ-$Zc&(t z3m33PLy7RC1y#~Xck$y&*tll28rrLbKa{@M{IY-5d8FXJS&zyxHPvFybyaSu!cO2w zL3ruY2~m-nV;qSZv9rgHW94HLNg=cr@GBN=UWoK-2G85L`q=mb1hVDa^>>>MdxOeS z#az^W_+a48xN@PWXe7HwJS1qOMjYQ|8|k7nJbJfLSftisS;Qg|G|(MtDEIsu9J7-K z-acrrTfXPpJ)p1gBh`5Cge$<3+i6Gu-O_lL^S1Q;3ofX$5Ia zwq9JeZZQ|SaVS9;d+CXs%?3|12hSfPdeobY$uwrgSYKTxQ_TzLQDHtYR^&{@g?l z`Q3iC?I8uh_p*W;h(1&euKPNB3R5C66jajL=8~V)lRt!vZsTvYf?I>ty@xjvx{cE; zC;xIe6CLt8rETr@wrR{r+S{BY!ja&Mom~I5=JavT3yrZ4;MR&)=Wv`e67`%ilk)K+ z3KLlai|VlY6ZOi>V{%4)PF*UYwUFN-9YNmNPU!zp(R(wzn5=sCp}g_ZTJb*`2W1*F zcF+LZRq&Nm#<|*;Zrh#8_)lKvtO_}lEY>l$-$=NaFsoM`gQc`lb#R}n6;p$!R;&%B zpIMsjykU9!ROUTfHl-KA_k+LNA>HpsSx4Y3;qOeO`vWPH2;2#HhP%)h1~bi-2Vp2{ zI((|yBA(^utisEe@9LrbP4=D9ZrIs%%Sm-(hct|8xOgN$^f9w!a2&rG3V^mCYOqk= zqTak{ZJ~lYzdoSHa%1y|e!`G5L$EOfzev`x9FHPtwdBfm`@WXcd2KfmB7If2=1VXm zl54OY`?1jFpgdTE#>=T8R4v2Y8q=i()*}R)FMsHxXs|lmi0oRO^sH5!rd`iux+^KQE-E$u?7;=p+Aljg#Lw+ zWIWofvoSg>-&1@UYHGnTVh3n_rmk6g-s9l!_V#AzN$sSe(asuHRp#6;GF69jW3(F-%ubRB}htMu>f?wv7u?HZu z>kPTa0>mwUBr=I0gXM;^A-}MniO9{Y>=guk_t$f0x_p${GXCc*vTfiz5F F*8ib#;{N~u literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_camera_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_camera_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..caac7bc9a3cf89f83d1801f61fe5c389146f1fdb GIT binary patch literal 514 zcmV+d0{#7oP)Px#1am@3R0s$N2z&@+hyVZqtVu*cRA_Jn{o+of%W=DzR8?HOzw+j3KMzc)v1i0yP{4UFd z9J;;_uki$!mXx|HGyPn!Xr2Hgz@DTkJgwCwU~QnCIeCBYCxK&0O~=1o+R)>Sk60rhwg! zQ)j91shzm5wb-X-w-aX802=LYurI()YFz3G)C+0N=Xb9GX7<<2w$1F(T~*Sr0{(6F z@<-B#T=4;WB}5gd0>gPP^1>rPx#1am@3R0s$N2z&@+hyVZrD@jB_RA_JTSRAQ1>eC87d>L{!{=P|+qJYAQ%YMGdk^Wt)_QCWs^HB}eig_S-PKIgabh zO|}X1sLlNNzW2So*_rvIOeT}bMBq{c1v-*mNa|YCwWJg0+--_{O9SWuhy0yGpx3m{ znE*pzI!AoT6c{$Gw*oL&KzN;(P3x8<0bO7mU|hVLNz=JooMtFE?$y4k~U%l#2SbZU($)09BZI)vVo?_2AU=tXqs39lO<^Q z88bQdD6yjADA5iKF_EPN?%t?0X_k zeG%3_0B+_8zX1ldIW3D-vY$k}C0hY5y=0a3U}M_AHt^B<5A1mxXxGM;|ND|liZ5F_ zfM-Y}QQN0q-aZTK}5cv9WhG@tYx9f;TdXh4x9(Q?Gd< z=~&ViNncfLa+0(vsW0idq%Bo9z6(h^&bfMH~r00000NkvXXu0mjfX!I8Q literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_only_audio_hint_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_only_audio_hint_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7564d35421583149770b564864fe98cd2b29fca5 GIT binary patch literal 8148 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_privacy_notify_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_invitation_privacy_notify_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bc04232077087571b51b98f783702078d131e0b2 GIT binary patch literal 1094 zcmV-M1iAZ(P)Px#1am@3R0s$N2z&@+hyVZs@JU2LR9J=0SV2o%R~S9#MuuTVNETg$;KD!?N;S~c zAXVs6vvN~Me?mhEPSN*P6&{!_e9w@Pv?M>FGj`*uaak}$W~&m=LbH(2MHdD#(_t|0 zbm6i|IVt)zXDJ8>Mp zB)J|%(Oxg{nPyY9TD?}Q)uxRx4<(KCL_luFas0GUC{&8Y;`<8=@;q;X2t?i0Z@vf=$|w~I^lWVO#o#8(`{n%F96?kiaI7J2!j54z5XYT zXJ#RaqDSWu(nZ*h02Uq7Rz9Eq+I@V+b!apikt61iNil>IDhMV>`DRO!93SNyIc;tycN6#aOgjtuo0b07x3~JnxQ?G;TLY+DLooeF&7x z z_R`<3PS{ET03=;Er)~ZiFeKmFNwe9!dDQ}v8VbNs32Y?oTZ5#5?rtYT(tq8?Jz&uB z-!~+89K%<=Ml;6z1mG2bSIM|1#Bn@q$0T?9lI~z85i|+l=UxIXEiLT;__9|a773>n z_tKDDch<*BrP7V_2JaOK*O;A?TEFY&ptT z(`G6SlFY0+rmcjtjZ}>y$zLV?aFIqa`OmZ;Q>sSM71h~FCk6TAD{rMOPP%LW&;+m{ zX$`=3Utiy`%Z9_l!$APUBqwon=w1A>!Nn(Y9pmDYy0GfRWnbz255xm9OOebsxc~qF M07*qoM6N<$g60SQ>Hq)$ literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_item_speaker_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_item_speaker_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..640c0a702934e6b740509f38f5df97fb4e0e8cbb GIT binary patch literal 1818 zcmW-i2~<;89>ya(kxll925J;h5NMz*3RMAzQV=jij|;N6pfXaCRz(7)1Oj1ASP}?S z5HJYQN?`zT97!hwgrzD5Y0C&yL}^q;pwWatlK@_s%Pbjtn)$ zugBwXIMcANLMW(p!7d|RbbsLVRXl3+&g|X47l&(SuT>}N<8V5Y(Gk>r8`$8;2Co|M z;scov-ZfxX43;dgECBlw&|!cc1J-;GxbI;N0|+JHSq;t=uo2BF1M_@rm}Mc@7lU3l zCV~c=N#;)!<$Q z9@Vf7Rk*OD3R7E~2lza2=fj3lAeDh52R4_3Z6VkefprnKbF?(7f6fP;Y;4cC9N5_i z>q{{yv~#;6Few60KIrAZ9wE4Lu?Mt-K`t2NfB_SXa=|1IwpU^LZagr~g&jQb7Xm&X ztJ`n^9mv2)f#&FK_4Z0Q-L7VeR_u!)|L2vn9qR7!<*xB%N{iU)yN!9{|Z;K()?J}H>vFX@A9ten&Cf` zuih!hd~MJT?YR#1^r=nzKNc0s5ajL52@ZDF>&O2r&YLD12UxQ8Q)&sT@r6F?J{+HbtP%fX~Xnst^ow zVO;^n$dv~hOEI?*dISOyM@}NQ5hmm(p%_f_U~457A%_yoYMVk>%fwKk1R_%FSXh1x zbHJ(q)|bF%94uYixnNxgL^ehW$v~-FVJGJzQF#(ArNF${&7-MN9TeDiT8)r)kcMF5~F2^Fs z!V>z(NItv8`NNc7LkBf}X=C`UKATLIfZ5;wpF^uV@xR@%N}`?^=nOi7k80vd+;6+JPXF4O1+EIHYt~Vn?o%Z#OkHRyxnL zy*f2Ho8n*<)x&B3p^`VEI({!&uE#mBtuu+!dhp5N8C~7?Wk%ns%2R!l?>br1tX~pc zy=$Bf*^3WW5NE^Q=v@)EJC!w^v^A@`{|o-)v&qeeqxe4Ztj<`=>5}B_tYYbe-L-6+ zxX!2@`Ne^)`lBR6a(Q4f^-SdGKPxiHUraT{mV0vEx<uigLh z8Q&0o%PXMn%gcV$PLf}G)S;iB#+)G#!`L5Nl6pcj0?j=VX{+}p&KsJELl@RbP}Hw)=HbkaCHBe*C$lYr^-eOoo11G{r*G mwW7b(RkXHt2{l=2-QG>H|9<#qw-5U0abf!+L+%D8F#ZozT+lE8 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_layout_speaker_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_layout_speaker_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1daf364a29a4bf39fcff409a34930efb56e867 GIT binary patch literal 1792 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 VK4hf6mkj^_002ovPDHLkV1g<~xg-Dp literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_new_request_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_linkmic_new_request_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c740e3f6023e521d418e0519d48fc3615063404b GIT binary patch literal 1244 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 ST*Ht60000na*S0MeL5ZJ=m`x2;*rzFTP zn8DaUUPeMon3qe1_3A$Va|{fOjh-%!ArXh)Ufb(+I6&gqM`zbd{Vy$@F8W=&dQ|V6 zZp6j47Oxg{HwE9;?ohh9mziDgPKiMN`2f$jlg0P;$OufCl+LxKzRt4IA!c*h>#gTb zXU7!q|9_@*O^#`^1%re;lZSHS+K2}a^c&7EzOZa1TMnP#9S3GHj(mT{Dy|2n3vwB1 zSePFiV3YIHT)}Fju=Ieve3k>-gU+Un#okP({wHsj$`L<5y@5wYME_(g!wCVNKd)Au zc4#Uv_^~f(fhgCh+rB?o`j;s%u-C9LU12c(8QQQ!?MC6xby^2DseSnTX(IQ7Y^E>E zpRZu(-sPai(9^)6oN$1H!+?nmlPR%*ne9shqjG{n)AxV_4J^_N8yGq7sE8OSIOZQ> zWE5J%#lPx#1am@3R0s$N2z&@+hyVZqe@R3^R7i=%SM70wFbsY6bpS?S1U9HQNJd~3Hs}b9 zK(j%+0UMYN=mxJpFpY4GvH7^ZyWDZe(tDB;Sy4y?Ndw>ppaM_=D4gjBzyP2J@K8#9 zrN-PMtVvp?V{%rf~0kRkV z013UUFCdj8b6hi6UVBM2{sC!>Zwz_Fav>OBlHz|X0+EB=p0d00wpob;9PFynuz&ut zC!AyJt>No>d*{*h)>A$P0;M9WQa*X%vd(;fQ4l z7qA_2f$@f;utuEVt0~-oB?n-n^zv0w*dhd)NwWmHMl-uP} zalWgT^;K&4#Zt(9lv+L>s$v9E+rUtw$EC)6TY-Kiwa)sjxrNlca9d&$AZvw5h^z%y zf^-|}7buE;L%mGG%(fdbxCF|LCISgHXuy?V4`;F-(L7qSe35X!%&;o~?@l$x5%IZc zn1sxxSpJ3S*YYGLL9`;6mJ)^7LZTtIA<=q`tX?Og7+Fk2 zNKyAuk4Kl(wZ7``)gq;LxoUiuRG%CFR_Pa;BMq0?xhm&unRIocs=X?5NNdxJ>o)4x zGfDsTVVH_0L>dm(31-)3{&8}XmqL{JO>*oryF-cs09H^qAQB7!0I)LvodGIf0AK(B z001SR0`iBw`ma8<8^vBe#(HkM+;!pRj+GUjuiezzgv2 z$mqG{9o<9 z;5~YJ2>zHIn%qp-ga`lb+5fDEqH4E7l?SBn(L`e~*BlRP$xK#bxj}>-ENS6!er8Nj zixh!RcFZPxyfuVh>>P>~es)qNlfwq0%-9L5nBM>asvQIP-!a-d@Gb?God9O6YK|9= zTR$MlC<#zgXuudeT(qdF)XO6 z4Sx|B1Sk5HrVv*kFh6)*IbD2?MYKU^?2SJD@asaAaNd}gWTu%VTI|=<_{)_p6(ix} zcrw!8M3vn(>0ZqE2JZ@;+J&iXGCt{74f+7JR-K=TjaLz$i5V<3yMKA>4xUwf+?@ZO z7;QCL-BG+u+!?*EfySrjja$=tWI_OrsoH^Rg55TZ>Bix~X*IHA;e`G6 z>jTNayVI>l+!%>-=T#wio1L?Y>Yu4q-G+{|ZG?Y8A(`~Ttk(*1qyM$~3efDTi0gTn zM%iZ7?B%}mEy$n00NrI1&ba0zcvhFQmZRN^Zf;?^-(JMXn zbmdP}^hUwFcw8Ad%kI=|AmkiHXf}pHD42W(6l&~vSp&lHk2Tr#is~6CnfX#B&fgXJ z_sfd)KflGsXDg}wCcf{xAuN$9d6CQ9yPJ-F#$Y(#vM`jq_3la4uiO!PInu#6#Oj^C zaCGK1Cu+zK3#hP9+3r5=G$g?N?%k%C6J$&%e2M8lzA&M3ayE1;ank#vcUd3?)F$(8A0HpFP3(}A8kYSuvE&~-(w09- zTP)XzpPgd`Wf@%%&p^YqbMgdocAt|3sGqJ3@fhn>Wy7by5SXAtsFG4%BJRr+sq`b0 zZ~QnQg)*hmPBSkY;f_q+j(l9UedUnq>b|!Vb$@>s!sy?rCsn(iKEz0X_+XuG>mClb z;SP3Jium3pG)FUzXtWop+RRWc84u+$C z=ND9l2VnE*xPeUb_r&J$N6p2*UrtXVfvQpi!i6R)D9P)gAsrJZ7xly?_Gq)vK*ImlJYVP^w+mU~JQ{$s3eNlW zzcpuKy9DUFXG6D-bzv$Igd4sAX?7{vxh3W9RbbyL*ML9T;C9tz9n31+|`^wIp~?dNOIjgBMT)BwkwoiAnV+569=)ce6r`V`qkxxo$c~|209I+HtjMJ zV`r!Xm3_kEFN*Hqi?@teO$H?VJh%X_F`^;TMifUDXhMWZ-Y zy3bsi`K=Y=nUe`mj!?&PYu638YVG|=SxB8|Fs#=s`fA=tVpFoGHIA8M$OvqJUJcI zdTpNijAL?g#|B7IXS|%Xx&w~u?yvj@`Va`6LykVhd2_nIYk>_^Heh4ZbCO6Y7tUoz z=KYls6I<*j`=@`-Y(})EF^IBI+Y958SOauEFz@n`2J;Q+R~fIXplVg8rwiR;(anFq z|M|b2;;?B)#=w;hT<}9(|dP@2xPE=NHd~E+E8+!FE8aGY6|5iim$x_4@2OH zYQrwC=FV>PZh1uvm5%R62PM2cN`@<{x*1^R96WwsW#5dh1C!aDQjqw54X0xB4FM(Y4vh=>0HKW#M7)ZoO4q30+g@8K{N$JNy0sj} zG5&RmMCRjIKl0iMnPI@uk4-|r=b>>GddHqk4xPC%NpFXd@)t4Qo6i~t1=YG{%@q&V zVt>f_B(8$@AoeBg(ff^3-OJ!~?r+he#l#bJso%#yFg|Ou(`9b7l;Wd$KdzQYw}D0^ zsc*pJajh<3ld8+Iq}?hx34L>x{$9Nxq^S{2s(#v40@a{<`!GCz6iN1@-c@CalCWfS zthz3q$=9626jR;2qFas{vp*DN&cTKiW2GG1>8IAgYlVC@7&SD^xc~pwz*#r#>{ux= zeK>qMJ^TEOCJP4igMg@+#*+O^giMVRmGeiCf<%LSaN$)uIIs5R7#LxtKSj>C4TyaC zeMpS8N(tL1;qAqk>f3&MfKst3Vew)CisLl^`C>^*Yu4?xq2e-Ue7B(COdgCxV`ICF z&c|t^;SW??%83c_|6L68PX*AP@X-yzQA*mC@+N<8;+G-pZvW5w!2!9<+Nw}}X>Gzt z)T}I;*W`;j?|HGFO{E{PTG_I*iGVB#aSo>=7f|4PEwj zDz0oNj_|{D9+SrMpxY*xMwsi^e)X84^uHYN&ic|PK<2P&WX>(PP1{PTVk{=ARLV2P`Q;H zaLtV1t}L3MQvmTX+R;GGai3TIc_r1Qq$bpZ#D>otr6a+qA zd0%3b#jlxJjJDW*#OF_^n>yB*X>1^jFZhy7|NOkA(dE_jLdHBD(<-kqJfG1ew}xNb z(!(f7u*c+B=y42b%m65sm*Bx6=~rlxuCMiT6|ZVGJoVe+V2@ zXY&lHww}}IfdA@QldD$5!Y;bjtAFBo@cnr|o@`O#i0*Qh?O^&PS~bWZkWg6)$`Qccf%pOY9nU4eBrx#-f}6Sl)@SGe`d8Mm`vK_m@00kN@?Fz_`vCV% z{)@^##{c6zhd-2me*CiI0R3h=qJ4Y`F)R;gy}bmXi%m}-U;zIA{{c(ZfB%)A_hC=} zkouW?($33sh9R6f%vVZ}|IT4kzx{_v8h8~hsk7W)|EK;1{4=Z;%kX2T;MdPjbfb6X z_e8JJP*pd$G+Tcxms#(Y8BrcUtAM4C(H3WYyD8nZ&0z=bY7Bf82$HKNqyc`=dS~#g zt{(%ECfxt>OwZ@|CyI~vr}sX40%(C{APm{l(KO5-|JW=47N`HnHvd#F=zmZj#Zm9f z|2zMx=i)gMcZ6Y#%5(k`fAr_nivAP-#^(H}XWLbOvD$)(;btTyOWP{!;;(PWohexs z1E%0U^f!2mk!U=EOYy@#?jgmphS$?h-=eXb&WWzs7&>qMfPLIX|E)&9*vI}ce4Kjd z$UNWsu$>-PcdYdE*JP+4`J21aSNyog<9NFTo+{g?WrO*CDWfU5-|Q#11`5kgJdM$lMTrCw&)?j;b>{{VF3d_x6RP&gpg0ssKC5&)e6DjNVD z00000C9nc?$`RBaU-+y00saG=Gi|${`sI|f$baGXfIqixfcndHzfNSA}=dJNYjqKRkc5 z_X_?e{S*7Y^e@`4?p^u420vg9-}$9>a;qQn^+OMAU^+GGpz~yf1?Jvk0092~{_zbv z^AeJ=S8r{zz9yNpbKlQBXc6k`bplU02-Yr+`_0>kf7Fie7VTOc(QfsO51ANb>WN~Vv(fQP}TG69;P1X{6wsNMTaXnihCQs#-PW(X6# z|Mm8!`@6sU@0}6!{-*zL($~eKd;ijDXW)exryKGMui#!E{8{|kO_>D~iF7-K)))Wm z74VmT@Sy*l!1_6lC}`wY-7j_AmL!*>9z}e{FXvSTpO!Gp)&ghYp#7^eO>m+g8GajL#h>*$pq3!Y&U3!0)#r?0#Mjy^>Ae$XoFmQr3PPaeEFd@{;k^qNswbf{BlHr$5AC_K^5}on17_L+jMfB6QW#gdY$} z{HW_+@l%nl&Sq@=cl|ronX#NIm-7~;xWm`Ap2nj-#99B#ll9#~-m?FK#nO+r{Vu$V zI8*g(m>3|rHfvx`O3xnSw#^-oHWEI+_^a$D!D>80Pb;lql`r}l!Tl%(L}NJg0}}uct0j42X;_Sl1%VO<#RpLQiO|?Es;CYCplo8PctQw~2J$Bc zk;qoy#YQ$5L<+D1dzoP17%G|=OmbpG5Kk~%Jqe5uf_VVg###;)YatQ{Bhv7o*sxG? zq(!V1_=m2AXub`@z@Q%#T8I_+$o7UHEXEy#rbG}yCQwrd0bz6)WM&RUn3x|%8XJO; zaD*ugZVp2jL*NJtxVZ%!0s7g%)^Z?JL_na$aXW{fn~7Fd;9we!Y5{}A#Kb^jjG&Z= zAQ-~j+#Ci+!jMRahyjVDlWF)^2sv{9w#0ul?1+(s2ojY>qL4w`ns|Ro6wL|@7S%z2 zISHfwEl!U7nU*LwSS+3jLqOrMA7qhx3v>h#PoqS5QYfK+nRE}P&?u3?6e8Cx`8I1;J+ zR;!I&Ij|LY`eAm)vLqb%!A~g^isZuG{cMl+-MyiMDs53fA8@1h922IabQS6CCycTJ zl9A|g74?FrrN6vrKBL)aiUr|xPCtZJ=AO#qSyv2O9rO(;v$~dZ&)O|0vzotHUK8{A z+v_h|UGd*PWh(7KrQjd!5ZvqA<&cyNKWNPKxTT#Tw-fIfEOW;e4OHF3sp$Q`(#vkD zk74TA6^*4LKyjyb$)TIrU1ET$H-MaBnZ_1{#!m6_5vf6}kc~T=G=4>ciIxrMyEMC~ zvSKfK0{X;nXR837e|+%#Nwuu&lWN~vgO0#r5GpTm_e92Nt#Pxd)cJ-Qr&mSe}o0@W7o zU=6P(TzfsfJgHP49XB@o;a%_3{L853)A4)I#zj|ZE>~%^z>1rjpXE@oyn@iuN6zt< z>t^3pn@v>GJG7?P8+zYQ-P*UB8G0Q)-h1$xdd^BzUX3DU-+4uhD+RNmbVddDdjhk3 z+q|#BU0N--sqj_-1V=E!zpqIjelVv>C({vWu~)gO zm3#V=UagpS*`#&6-C-$yc<)m{@|(qUyn<+UF;Pp5PX6w!;Qg#V?<>PyJy09?n@(=A zYe~6$jWkr;PoLqp#25pAD<%Uj>Nxi_jgo#n3Dho>?#Yc%NyabDjoVx#&cNagLtgA{ zQE!IpHq%`%W_6!fKXURq*3LU|BTVu6;>>N*GX-|J{AT^3OqH2JDbJ)dNA8MX>Ae@J zz*o6XS_JhoUzJMI+1$a=#Au2cgnPd(uJO&_sMyUqp%10f1JciQF28z{VJQ`yUoA89 z&x|9me&%>X6>1@LzKmE8E`=ebn%tH3@*o|A%n`TFP)Q^HW7S6@*D?<)t&E|GOFu3#ay$0c~f14V5(5A%i%tO zhko!x9~!FVpnfmo{0|4Kb=3V>EeP^RRr`E4;!{!q{Fm~R`)qvU?f&}*8N4zHRi9$9 zlCs8;v+~x3w!!qkZs3|N2AG_9W-v=h|T(Wjj>9rK}`SGb*W>(MG?7Z6&m8<}uo?FsX zkW%Bje3z7Ed5$VSq)U|Ve_#n2dN+|c5IDHrM3c>N4XoXjkvl-^(mRyAiEGJL_e~nc zc7$A+0WP>)9vdG8UK%$jiv0pn_!A|EPMR&%PrH6ytF>LAOU;)6_*E=Qh;Ic=E(^LK zqnbk7gjcIY7su9+77P@1_G#QX=xhzN9B$*~E2cTL`}xdoiyX4S1&yOum?4Cc53l=E zQPa_}Oa48(*94zAZ~J5$%lZeKC?!F7ropUmB7CB; zhZ^%$tzEsSI6Aw4>CLE5&()oJ6OQEx2F6#1xK?!w(+e*A=Q#G(32)03wTvo_a>e47 z-US?MGw#u;AtcFHwqyb^L zMLu06DDzCkJ!`G$Q%lqZoD38L)>KSXKU(P8*eZ!zHKlESzRjM77u*;)uMODM3T9nC zpWetdn`+R@)Vg6gVm#7o=n`Q4d%LaevwaH}b{>%COYvN#3Y?xMd^Q?Qh{Y5yM;YG< z3(2|b7IJh+?u&oEe%ppnN>nMHvoq z@8+hSJ$Bm19v{KXR(n$O@_}i|3M;jvRhZ6ES?O5$Sl4G`P^k_*9d&lMYSOFe+&W%Z z4K7YPtjJWicE51woTqPYdOBQ9x#?e+rrLts{i*(moco?S%zHt6`7lGhvh!YWXdG9b*+PEFJozOs!2114dgD0{6^2I@+s^gRgm>V>> qwA#tI!0Z~j7b^Q5N0Pb2xd3Ro-;b+-CiHIKy`1e`?O3*cm;Mcia(yKL literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_default_avatar_teacher.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_default_avatar_teacher.png new file mode 100644 index 0000000000000000000000000000000000000000..dec81f9af5272019911dcd07683ce4b9df41bb88 GIT binary patch literal 4396 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 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_kick_out_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_kick_out_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..49307dc6e2475bed2a7e0edb8d82ba432041e5e7 GIT binary patch literal 1113 zcmV-f1g86mP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91ET97b1ONa40RR91DgXcg0CO%90{{R6!%0LzR9Fe!nOlfWQ5eVPVB}sT z_k;|RG%le?Qqm}S7|Jv<5^pkjVO~hQ$P+V9coJ`nBpH_?8es|##=I&q$&_4TT;lls zkF(C~y{)sa>y&);Z{5EC_x<-eYwxwzOs*=W<@5PDP*;MN8FJ)kp}%YCD)h~<(- zMd$`N2S803?ic#cf>wloDC3j5JGNkijvz}LsEe6RGrkkik7N4Ba*HJxvHHo|!J=4E z2b{iBZ9w#cfv#+|K{4sa@k=UJp@)JqJn$4XTv()Fk}V_A<_yWk!EMRF_faDS) zzd(-?>>`KL7*T@XILziGR+Qjw1pja(`iYA;p@P|=K9Qu;L83e{Za9cj6)L!x;G}~@ z?L7P|2XUeWlc|;^>Ce?)RZpP410C4 zUF!h9ALzzmGjo7%L+pE-Lzce8f=x1nXTBm4LzjXzpdZ}j0e?~cn}*nt;2!8L;*$EJ z)W-R&Ma4)vz6s)N4|xUk^HHLQcnH2K#N~9X1q!4a!vv7@J(OOvEl1^) z=xz9a_BxyTU!BHvWTbh({w@v(|735L88(kTluP1jXO&4|_8A8JWO7X(An`n(S!-_p?R ze+GLgRwGv5<5-qNwE0TxBC-py5_l+ySP}4lO;HbCsvR)%A{O-JcskAUGob5uR_h}` zEdq3$EEzfW(r5s>)P|Y{BP37siS&ro&KET8 z4+XIrkYLxQgHkIZ%6*=E`69$>X18l*4XF|{tk`wn3S#D&M7AdB?&-fnJyfiG&GB+L^;y8h!Ci4}*3H}Qn^o4a{%NDX@arq^ fka6Fk$rj`{;=CVyjX{)b00000NkvXXu0mjfks9)N literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_linkmic_hand_up_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_linkmic_hand_up_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a27b91c56d01ee9206b1429ebc125f0c6758197f GIT binary patch literal 898 zcmV-|1AY97P)Px#1am@3R0s$N2z&@+hyVZsEJ;K`RA_MT!&_ z5wS~|;u;}E3jY9$fP#W4Vx@&(qeLqUkst}EkU~ko2q}aVDhg3ha-fid2o?z>kb|$q z?rGfY&dkn_yVK04oq2EH_ulN>dvAeABoc{4B9VT9WQF8B$$gR=B+v9Zrl63V<=^c7 z*P=;&<8ih~p6+#QHi&AGgs&9~u^nbY>O2}`h2&2~AX_vzawHoLVwuKJbJcT7w;{bLmla!v z08AP@>$+h~MbrRXa`a(_L3UO&_I1bXcG&2a;3~--O)z5$`zcR?NylTYJ< zKOi|$;#e}x<{UG(_df;6S0zQ0$=LS_ON@qmVtu3mAbrOkTAH^3tO0lp;2nTZ0Ggpk zv#x@x0Jf1#BYe?Dev{Hf@{TtFya%u>BC2L43?%Pb9BUsOl6+M5)o{viDtHvY2UkB1 zv;dqJ5u=W*Y4c-KcNDD~;(Mz=TfX@sANww71 z_!j)tvp?_n7VL8z8-ys>k&`7@ME2nLDI_$$GYs^3mO}_`2Jq>P5Q0Ak@EM6jB9Rlp YFBjh|J1`f0ga7~l07*qoM6N<$f<6z8jsO4v literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_list_item_ban_chat_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_list_item_ban_chat_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..96583c572052b76c37ce9ba67ef384419f315d0c GIT binary patch literal 1395 zcmV-(1&sQMP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91D4+uX1ONa40RR91C;$Ke0D9(TtN;K6-AP12R9FekSxabDNf1399>Hh~ zil`95P2vZPpv*=QaiJit{E#>>2ySAK;0Q8q+-NdeGq@RoXclJSLK2LEZWPp&U$W7l zf{Kb_jQEWaKZ#!J+T|oRsy|UElbp7;1~|@UDSwEG`aq$@ z7hX|n5K5g@$BsQ>M_y8S6rA0==V4-EkAT`LdQEwBMRrJl4xmu@UmZRAs#M*Q06OjM zwfOe!A2GULz}1#&JXTJrG2wTiy81uW-OYL`Wdd|sTepdYZUHtw)l%M0rA9=hUG?;w zPE)N)>U11O3AjT7tbfwMaZrA+*yb1_r!jw zvU)XeTC&R3tI1}FLFe2~3b{V$?hs7EVVX8=^1vC}{NQZbU&N#VVto8>nZ4)^F?VjZ zsk{<&le)TeEn?x8DrA;;ORPp!G{|G+(wJYr0{89#uU`Xi-bna~+kg3zrlI@vet)pw zo=U!dZ_3sPNPPSVJboNtBvhX~0dCv?2r@r45nDl)c5`ms6DNSDPjjo~RuF6i$n#u2 zTDumQH7j0cWCVEm((kJk*WR!JSh56|JsT3C!0<3|^CmDj=*z{`1RH&jhs}JnVg$QrDRL+u9^lO{|6mFo^)i$Mv#tj2Sb4=H|#~v5fh0%-py!wo91x^g$=7H<91p z4_v>V*o`%7fSEIs`@=o!)&Z9;0iQ#sEx}fhyfiEzb66AWKYoOVu-l6k`R()Pfwyn{ zwy7~6u37~&Hp+e`o<_eM8Zy25SFmyMc>`N)_hhuTZwFX{bnYB*<%;H*o#Op_;PU05 zlwIfI5g^Iv=$85W!T>ak@_*@fhRjaERJ3<5K%ikVvu5~4$F%jY0OY;ZasIOTWwe;% z3_X7iELfmh3l{<`Swx*M3AQQ$cs9&0t4+T%d-t_#ycCsg=8@d#U&UON1zT0|#vk&| z6x*Yt!2SEt^6VL4PCuNDG~WxF=gxBKRFGrpL&QcO>JL;CS31dc;TX3*eqXOizUj&mqY z&d8Vf%cqV`96$bVc;<|~M1V%X4V>Tc0n-36b~Ew)p;%@w!SA znKKw1$9<0AD+I7bO7_+mRG!L5bbB1#s?@(BegZ)wvUUID3uFKQ002ovPDHLkV1l=J BedquH literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_more_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_member_more_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..39515e0e00cd8b12f0831c1e706e726d5bd4f722 GIT binary patch literal 1506 zcmV<81s(c{P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuBOi4sRRCod9n@expR2YUcDUh^j z8)$(RN=qxcV8KmdjgZ*z8`!e}Ar`=n4J`Nzhy_1|RS^;rRS|*(5>hYeg`_Qo-e}T7 z!}AP2mhG{}9($6E?N55gKF8@|h^$<7+9?h$4 z3UP{Y4JgLu6v~@xEC9rJaU)Ly$$P#X_JB&(z%_(;*rdYR0z|I<6qP>%Z2g@uyTm0# z_^WQ^wFH2?gV_tffo&GdG2#M3=ou5)!~#J6acVdYw#(hC5^@GPhX}W-W-wi40V0=w zmOO_isbB}vUPgq~s`XY90P@b+y1dg`8_b#FB0`kT6cQV2QOlnoQCrB%$HDn|Ps*%R z017w;?DuW6gEU@gcO5GL1ss9(lWk+3xZfji7~6P-0+3PSr3xl0o7K}3aM@FIbGZVL z!S(ymqD(D|m*Yt|21t5d{zUW%Z_z!Pa^0|ZJ2uYMWK;q>#vMjmhWw^ORO<76+ z61b-CitDF{MuDSnOmR*HNaU_=r#3cuH$3e)yMk+k*kS=9Wl|U8RNXo`l=OmF065w| zy4?Dq8TA4m+6*lzfbQQHOACNYEWx~RvCu(Pmf*Z7uiybA(?bVIXDK<|#{%rlUhP46 zxYn7EM#Mh3e`wo1aNlJYu>V(jFcNZh=(tY-`sn_l4RW zKY`Prs=Z3W*TH#k3iwpFiuox1P2jVN@4#=Mt}P502wow#tD`#h1)1JXWc-TruM^>- z(|5S=apK~)oPPq!UWDqcUxJr_X8KRTHwJ3heOs{Z^Zggen=zPz4pxDpodTbMy7tgP@MUs0nF*|1*RMK?n?6|GeCBVG zH`Mmk&`_a8o8sY z+?nScy7TI-juIS4YaQ;xLC{3b>3y?dquT|vJ_>L{;zI#&1y@yl8Von!d^Z-r6RgTo z^#7FY|Gge4gf3wCPv9R9yKWBp{)uX6u>iP)Q{nGXe3uXYy*Aze#sWl)9T>Xo1rm2B z8Cyz#$P2E-SG#v|1&*mrR7wE(l0YwTJm{J^%f)>^kQ)&oy5K{KE_DS5KL1BNvgFSd zfQ0syb6_L`acwmJQlGo)%@sg~WN@Kyxs7Zy_k0~LBd#CP6bfJhGP*dr8WOkg=z4!; z+J7+kwa?g7+2s7U2~g%mir&ujVnJA=i#Z(?fqV$4dzmJrHs5pDhps@MDW9? z=RBWboBjtANwSErm+*10kc^*!b6wr3ZlX2JL>>@GB7*Pa^n_XYE4^Qto`?LzTl!i8 zB!pPz{1|BZVkHzg>Cskq>AqH_zvmU+NB|4O8!Y1hI1CoSc9_H+=vE=_!<^dISb$J- zB*cEg3gI}h73Oz=?p3ZfB_3{WY664;JtBslpcujrsY}-zq$x66*g0L|x9hrkQQ=!6 zK(eyPGnR-`2!(OH5DugY<2|_daKqwO)lHb|cH!sqTe>Ox4-Z5!QVr(<)&Kwi07*qo IM6N<$f_6f$b^rhX literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_allow_viewer_linkmic_active.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_allow_viewer_linkmic_active.png new file mode 100644 index 0000000000000000000000000000000000000000..c9b633f58fffdc2874b889440cd568624913ef00 GIT binary patch literal 1689 zcmV;K24?w*P)Px#1am@3R0s$N2z&@+hyVZvLrFwIRCt{2o6m0(M-<1uV@SCW$x;u5+e(!<6@~r< z*$9Mks6>)~pytxT2~c|{xwkT$-1g%14`>1shbk(H`3quHPDs`IhI6Q5$+_?&`SvjD zkSsg1vpX~P#_UI0VaA>}Z{No8sHmu@sHmu@sHmto^N2|+U<%0qKnUO#fFQo= z@z(rCz&)%>kn+^<_q)D=# zJ$gwX8OB#(rAY=PcRd($#4hDpTwX}7@w991le}L*PCz#SXt_4=axf#+nRA2 zuEw!ZaL2%)neL>K6VYMJNa<0LVyqokRH-wHAbyKpQOqZ^DB1&80~9f6(tt%@9)Y60S5Te_T}6A~Y5*q&&9io%>}M$7B`Vp@B8nmg zO?%2J_xEz6!{02OgjZxk{mx^=j&3QS zI=kd;e@*qy%vtuSh|2@O9|pe(0X)=v-&3?N|&l{mP$UP7)h+bov=ly0THQPkG>`V~fR)K-w9y!`wG}7T^>e(v_xI zj54^+n$V9!P|iwSeUxwZ={RpNv9O797o^m6dti>u7 z)R#Z*p4l6l1k~p{$KvKw1NBEF`!q~KpCxivj^sp_n_M@jE-B1Xi@}E)?m-|VkAr?2 zdJyOd;suV-`TMTur2WY2PKol&CP?|JD}?yQ$Cyhk2Jg?|A&7>ptoh5prCDHZ7U&Ow zy&>@OP5h-mXXX&M|GF!BC;NCaC}l=R6)-Ofk^Y2jxc(cL0W@JT8|P+$n^)vDH~Z=L z2XBGRSHR{!z`;8V#1U3b&Q_lWZ30LO(mO(kMc3oqXfb3>`2dZWn+1OUHro)w&&`{Cdb$!x!qs0)+m8$!M z)vM++Gs$Sp1<_b)G4N$j)n9n1{%D{$H9KPh!0Oj_{cm28|9+_9o-c!{+|PO3Nnuw{ zI)6F8t0$S8m2w~u`ZB0$2jo7Gr(M8)si3Q;$stkq`Ia9SflcS4Yo|hvw>30KYZT)2 zuEG&kGW$a}O2l${z6_f7CihZDB!r#ZJx2!J8v+pi47!oh_SnlvM8~H4%QyD3^x&{4yr$tYwq@Ipg%+pz=Kih z4wy270>>Hqwr#=$$jsPp%p78UY#IAWbECx&HG~vch_|PKrO2KT7=Y-UKf>drAuB2> jDk>@}Dk>@}rilLm_}R4E*pK|W00000NkvXXu0mjfv@0<7 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_allow_viewer_linkmic_inactive.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_allow_viewer_linkmic_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..3c278456a00ce181df175f69a7ca70827fbbc191 GIT binary patch literal 1743 zcmV;=1~B=FP)Px#1am@3R0s$N2z&@+hyVZvc}YY;RCt{2ob7HCM-+zN*^LuN1!9Cmqz1KHRRYmU zg;ex!*<1n171X%`;0kcAAms|2J4kv3cKVkVCzYrL654GANU4MpC>2he_1ho2ZiD05 z56_H0!akBEXLe`K+2i>*bIxploSdAToSdAToSdAAM~qs5w2*WFxB%_|aH3Bsx_kh@ z2e1QR7r=%P;$X-sP6i~)Bx}r0jiftj{l^B9%Ot%44B3nK(HoZJx&}k`vQDy;Ed2~Y z(jnO}V9YKJhI8@RCo-mI(3o93lSUnjRi5EctO2;0aH|hs3&1wQ6}`KXmk_S{cK|F$ z-{aU3LM#rZ?GPb(lVm0OxEbmt&6ys_a)$QGOz!RLgFNHVkQk-GgoS{loABV(q&6h& zmPl?Uw7op|6B~qKkCd^QP}hs8TQRJgr`o=D7%nDBIFh2 zF2>DR*P}+Ck>T+7B(iF{6@*Lgr27>YPQ8?S$(G09GZ}Zb-_v23IE$S=)DX2~ag??@+EspB(@j02YN1J1OgS`AJcy zIJPC_jzO8}VE@%UwPGaqhdrN3bSBAtT{2X9sMA{@gzz)em#yL^1H-bmwRse(Lq4a6 zQ5w{EZ^_WMwo##C&{K;I`}mtN_>%H0ZDhrfl>52_3~bOS3D*0|>M&@ME2e_XJ(77M znNc0`^`5`)GRy^48Af_4ly4zr?vcp|kgV-pgEG^@`0d<(E=fOED8_{$hrjh4k6crN zQBKl#JIOpaavH{m#!lk)sTA6K`cLBGigFaxoXqr{%T za1o1RlY^%~s)Oh>7BD{17TXgN>XIL0k`9p0ryf%TJecl)gBKa!WjNK8qL0I{r?00l zB$*<4I4Iil@(hR357D2y0JhQuO(LV$U_O-Q16ax!$eB!-AH~rR(=Bj=u+MSL!<&HN zyyzJ+=1Dw`^Xje&!(m<>f+2eu$Q>JN7@mdlMqtb?`_vpa7}@DNlJ@{)@dbAfMz^*R zh7G&t>VeQRxQQ^6+WqciXnREnVKUol7N*PRlaWKu0aj*){%M8sWZ+4(9s3zNOn2Pd z(=`-R8g?=b%5*N#JwvifF+ZjenMPsqIZ%(;a#Dlp;qb#aY{j%p?JzmS=W)n87*4Xw z#P}nR-b6p#ut^x|L+_arPeSi>N3EZ3rc5>-8O)VjUK2vpP06k`nvUJE??yUwU%OGk z7Z5(l?G8HirSGoS``u)8r^GN)@AOj+;ZaBJ2g4#mK49d>&Yhb@ai)OcbOEiSHd;q* zy!rdRvK#?X5A0xdY4N)MVYwlqo*_%ot_mSGbjz&$@^sk(){D~xXa3R!%wM{I;!NSx zeaAt7mwN|z`PV*&u&YzHRr>nNPcdcNnd(m2cG#oUjOy4O z`vG9Chn6MfJGzr&wMR{tpu2GSV(OmROL3-v`AZj+^dMQTHJXkogMKb4*Zx9+10e#HOj-nFPqJAoBE1c1HQZ$$Xe-R}VRTSsl|K7EmTK5ZSg@%Z;Y)uT=9taRg| zXJW{Ai9&drQ?^xFxO@={^QFE!sMcW{d#~SO@AX^NmEG?E_q(Ax;EWj*h$8lZT_wVN z)!g}66sJ!_><`;`^G-v=UWkpr3f6`eu^%k8@vt0lH002ovPDHLkV1oVOPs{)S literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_high.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_high.png new file mode 100644 index 0000000000000000000000000000000000000000..78d4346be3e0b6389ae3ce517511e9be48ce896a GIT binary patch literal 1305 zcmV+!1?KvRP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91QJ@0=1ONa40RR91MF0Q*03Jr4{r~_3gGod|RCodHoLz`bQ547TMMxRs zqcl-ON)ay}L?Rz05&0TSqefK`+=5s;{g+divTcN9s=79sYwz%%iJu%AlcJ4#jqy%@9hIy;0TwnqB8Kd84$Oqup!vtO(XzRM6zuc zqw&pAp@hi0a1e6>E7c){$YD$na{>`JLgY9wh&h3X8zDx+9P>P0A2C$bo)CkSNFYEg z5g-o_5CcR91RSIYEipiJK)^wY&=Lbg2Lv3X80H{H0Xe!v9_BU8&6#95b39VyrKyY4 zgcV&j=aH5x)o)r+U84J#7UGO}B$(l-g>fo!WZT(^JWcUX=2W`E0ipaXI4>)7it#1&?XCAah1FA{m%jEJABEhWD&}rBBGP!(($kr%@cX2E6 z6=Id_7eViv6+s;2D@5`dC7{Vk6j7XRmTR2&8XtKx{bRKy)|Znu+rZA@BIKvAGn-|B zh#|uroB?$(i>$kxhRb~JK3~qV?qRTuQwKFk% zu$kGeL0@{;?h~z!l6{~xi^0?qty_W>!k)F7_@N`>hROb5f@pHyE@C@H5;<-Z#p$N6 z5IfOz$Z_G=bWHu1_zLm42FqlPFO$nxh&MEJW@~(zTs}g412Shdbe3s+nOwd>C2we(*iT)4(IkY-v$So0WJ-|$4`S-?YoWf|$X>g8^ zZ;G}7-d9aIU5B6xQ_3>AD*_?_UCvZn5rkH_7OsQBZERKqMAKRW9#{JgL+ebB)x~=U z5datU0$iX2V&ki5hycc~a@D;$6WeXjSx~3KS9RYy&FD|E2k478u)4ksamxCy4G92YGxY)nPn08UGZ8okZhT9tD8&VHe1Dz}i!aBF>2Zg@{Se?|$?E|z zabwBB@d^c;;pph+;82vyJqCo@I6y*SpI8(Wv|)!o-EIS;3w&#KBRKVW z7*+fH3odW|`p|MH=ivCNYvR2R*ggmsw>bRc<$DkC5-Ws000?#b-w6B##1YQuSPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91QJ@0=1ONa40RR91MF0Q*03Jr4{r~_6G)Y83RCodHnp=z%MHGe|RwXKT z(dgn8!3*Avkq00`K#2OFC?aYQ4T+bCC}>nPAsBpFUvy(kjF)%;R8TP(j7Ci4qS2rW zE^9PkR01M`uwXQ(=(>LY*xl)=shR1XuH7BjI>|rPb?VgVQ-4=gS5;5$5JTGA+xwuJ z0w#bVU?9kW?k0cJ;GJLtSPtIF<#KJLMN&Wx1YU>5JkY<$(ks4&f|(H6Y*G=C2!Rh! zc&};T^92n2N$xg?{4lP~lNj{C#(06hF3G??O0Iy&O`%0Dm;*mW;fHX@O67D7Bwiny z_25D;5l>*qNV0Sko$uVxR3z#x>?J(|}dP&bf#G6QrmO1JD zbn6;*Ve3Vrmy8T}5;GF0>YhYTq5}pTxbQvEljwi}2QGY1^dvf9z=4ZH9r#G%Vmn5^ zfIZ+ypw<4d;3$w({>5;ALSt9t@0a4tGe{K>Ib^*9})uS(;WIMh3D0C$3Zmb#16kZ9J& z|KaGa2J=C0v%HG@XT)=j>bZWge233*X$e#y)Y%1|;&K#tT{@S7@BLs2KGow}T>5rN zqUO7s2vj|>YN7saD!%~!soF`Iium75@k9_E@0T%8ROE6_e1ZVC*zU?uItl%mpdS1N zG)J~z|0`*M1jDWoWyRRAy#%`p3LN~O(F4#!-M~FGItm2cKI%?K`5x$1P*_E#VxS3q z?#1q9)0RL_K=&xP+$>X`@^46%f+aL8?7@0@3gu9EX`v>e}>3r%?o#YR(^ zHt&kWX3LFlL3f5lZ&UR|sUD??zs_cmQKxo31Cgi4{qW$m_SF2FNnDY*%M!&!7F}1W z^q}Tj0$6F$rBb;fQBTyA-ln1k@+0Yu{o--Z8-FC<8rP-0c12?J(Iyta>ezLyT;>Qw zbEGM|O+}i#D-vx(_gMn@JWVj2WZU0zpWiLI#41-Lj%Ju>uNn!%M27|1uQq_KQ9;*V z6vP>XqdzKDEw0vyeTiT?(6%iSh}5E2>#)Y)&3F#igTcu`s`a2I{LU2Zp-s^PuUcG@ zr~qa|)JG8al`R_do6rl9V6XdYj+zA2Ydhm*WNWkS#Yi~G#MN-t-PEHNL5zA^B2iBT z>%hZQ7y*_hs+i5lwhnF2;?gCFisKlt3?lCWwqa8;R*2Loj&>_gmNcr-0@oy}nMVL^ z<(eRJE*Jr9leuh*1R@_txvZ$box(PBGx1=XA6$idG>+~F&<2ruLvIE@1gQ=Lnjp>A zC=Ktipcim0Z5D@_c*s=Q5=<$T=Alypj3y1G6>=LOazUt2N`4ReMO@w<*E_l{I4B8x zW?CU+>c$QlH2@zC5T?1%6rJ^Tgy=ulrX-$j%!mk9jALO{tEWf zmh!TyS|L#{BQ3xqVMuG(*%}<#RC!Twe#pZU2l{+lwbTlUYJhG3YWB{m8yZynnuoK^ za59v9xlgr*d2!Yyi3@SRqWBhxG}~z0_P8ZIM7x(vb5-0Q*IH2PQ-vvGOhwwfD-!h* z(07b!r1ycJQv{+V$Nd)jvn{$Ts(Hk>ChmX-rPaxeaa}dnE=XL*jb{*Ge!WNf8u{U1 zCRhpn0HtIV1yiV_)Rgh2qRM;=^(J$V=PdQ7q8nn-r&48ICu)9~Mt}uGk=IM%O@XJa z`9_~hHF;|R{ufZaE!gcOEfVVJRA_QhL9ya}RPtqt?ys+h8@b0;vru{NaX!ghTUlCN zRuYfrhPM)szB$`=0$Mn$LFx@@WDdq!LzWeMYZ;V!DMY;W)O!(RT4aa8WgX6{KO4MF zV5f#ov!wXBhx#{X@lmcW{zp^(0XVLlU7E72B!>68n2R+8_%s+6D$}IYs|PPp=fO1f zlG@_?MDQ5)uY!ubJgHyVWgX7(d+C8p6bSYU(vN}OhB`0QJXj=Z7|IL5Rp2t(bijZE7rrMtBGI~rbKv`6cM<*dL_N`Z2yn17;Glgw zLLVZr7XP^w##hU!c4c`Hi5>Z&Jh;t4muL#qFaj~ASF}w$2G!6^}`Yxj5tL`TIX|R@m8osL`&-V9|?#794 cZ%s4s9|@~ literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_super.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_super.png new file mode 100644 index 0000000000000000000000000000000000000000..ba9fa2b07aaf3fc0611d5705e8558e16852f4ac2 GIT binary patch literal 1109 zcmeAS@N?(olHy`uVBq!ia0vp^fk5oa!3HFaPH^o8QjEnx?oJHr&dIz4a#)I;JVQ8u zpoSx*gMoqhzo(01NX4ADbMAMCy2>1|zrXtJrgv$o8h5(7M|8drA5E znY%Zae}DJ0E+OLF%+1AZ{Ke1Cl|MTp$h7JfcMkJ6M(c*J4)#}{#6R$VVDmxu!|sk3 zIpW+6tL%99u{aW|&Re4!l)7u?a;K~Z zLXRt1GG2+tCfWRba_qdGAtN57&HX8#(fPpl&wKpkKS+HLG7Gk0>1o+>-05EN#L`IN zfBEhfa=btHi%c=f;HlZW%ikVf;#;+gJG$ZaTua;5uP4PD*Ec2#&g80mzVY8q zxqs8twyAzg+PrIbw_ePmFG-VL9f*6dWR;xo#6rQq(7${)xOk3*SlMkE0c*9#g%g zyw|GOrkD4PxA5=RHL^c=I(id+ZCrRUTKAJ%qj1CtGx5s@)=&KYmILVG8Lx^wmU1TE zzZZFG4=2y@Dci4nIBv<~A$WY?bg<=lZrKuY}wijFpVIdUG{qH>xLdMSf8{r)0=EhjpL8#QDb0 z%aa@({e2QoM?O-0Q2Zd|*&USv<{#Gk)m=l)6BoWbq{m+(oY?d=W@dJ1DRV)~kB|Br zdQ_(=p2>L6c<=bPPg}l92Wob%(mHVXhSQa>2f1%P&b@9X5_omRSC)3|1IKTQORcgy z;@RZw(?9_AJdg9>jY+Z*Rx~Z>{Mgfa<$&t3LiQib(fcz4n4{`k&SakSzp<@%nR#aR zfy|uxc4PDF8~WG9o=Cs4VSC8_Bh!TEUh83WZwyu{GM{hx`R@_NH&?eEJ|MPd{hUOu z+n>utb{O1l*HEoqu&VaPyuP;w7Ki-yo;Q8tbsxR0S+#wezx?12ZhiFs{`6I#;)21` L)z4*}Q$iB}w8i?1 literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_super_high.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_bitrate_icon_super_high.png new file mode 100644 index 0000000000000000000000000000000000000000..50ce22038968adfbb4db125bbea024e2926e00a6 GIT binary patch literal 1544 zcmV+j2KV`iP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91QJ@0=1ONa40RR91MF0Q*03Jr4{r~_4a!Eu%RCodHoLk5hRTRfNT7l8c zw4w_nWf4RL5fqe2CI-@rQItYKlD%aG)>BX~2A|M_5cy&c5fv3ZWETP>A|KMOXb`24 zUFc>-S(4htuit-~J!hYNX6CFp-|_nn%v!MAYwxx8o;|;B&+M7K=h!(Wk;%!)lPS6l zy#ZZ_&PO|F+vIOfcpth8eHGo(>2&@j?UNoj0KA2WN6@)_kzTL|1Zx4gGeuEA1mJ@> z?@I$b-$URKxw`@RW?Y&<%tzqH*x`01fj{vq2juP$(aG_$vU)lQJhFjj|5P5M2)iO7Em_L?Za1N*rsUuJ6XoQa-; zUX2#-!Pt$(3h{N;&-RAaSq9pGZGrd+^{{y-e-2}YfBLAbODva}qt3{Ke=!=-Yt4fHV_;YH#`B zJZnnY0C5nAGYEJZkOG|vAhlutUY;G8IK=-EEg)H$(At*dE3*!wOXH3&i5Zuo-;<8$+jWyzA)cPJrc25qpC>_SJBfQnv)hxSpOxe*vsQ@3Do5Uu zmi-6GUIGf(OdOj1(sl;5F`fQrlY@m7_@uZ$YlV1yT$S1JMe=XOWr?kO;X2~}ipnp? zo)_iE$$WyoejPf*A6!di>AQ4r_oY^dOK5muQhPP|jc7WnY4qJlr}Q0oEO*73F|mK9 z9}l7Hlm6UK-aN5bA8}^uK!98Yoa_fN`6!#9Odu~p=c2nQ*KS;o5TjM%6+MO1mwAOl zrT6ATlxfoYl>YX-nb6l|l&?X}Vuh#%7oi(C$OG|#vDG0hVwMW=7vgvl9r}%+v|(c* z{nLZF>EWEd>RI)1W79>L^>PjsR$@HE!RCj8x|F!(_%#WgRu?zZKKgkAx{iKmd-ueq z{b@21L)(inc5u+ANVlN7;*m+YE^Ce2J5lpy53$oG^ij{NXQSt$*P*LWy><>I`Z3UV zL)Gk7I*6(Ji&D+LdKR3KOPAwLr)+2N+@u2zGZNE|Y8G3N7Pcwh^q$xzHs*76h-OsP zfex{njoIT6&8Vsa9bz>bv&SKtQB?;z#A-HXk3%%0st$CB)ojcjhiFDs9q16N*_b_o zc-S26fiVHCqh=zA`*PcpW(2fym5Cs}pWB`^BcPvcWFm+!=e8$y0=fmh5yEG&u(*}X zN1?z|6M@Ze`z1tXE6}WNpHIPS=+H~#p}`iUJ2}S{KGFLCc=|8@T%5od6Zj9aDF~boEhMJ^0000Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91HlPCl1ONa40RR91FaQ7m0DJ@61ONa8gh@m}RA>d=nNNt^R2abD_p-aQ zlg%WVky2a5t39|_g%+`uR`67>3N9#>9t7(}JlLKr=t-f6LZOsiY>Ov*k@jSvD2f+7 z30iSQg{|WX?rf5ooo%~GzJ70(Wam$km+Vfm*$vFRm-l_|d*3hbdw=r6*bci8akANL zsyoc>WOpsA`}(rA@(2CySyt!6ByC6%mPyuXb>0L8KI``hkRLJ4>Rr1Yn<|=igS8$)?A= z102~YpRvOUbv7+Z1J&tt_O7kLyMXW(GQYas7)=?#-ll!zVn0~4BUB4HpR4QD@A?#e zr!jfccDkQX_@3%3-*Q$4wY0SKq@q;cb3L4+8Da_leMxRJd5M2O~;T7o~v`#t?%E zBAsa|7-#T44Ol(O-12h!7!BUzQL;2;Nl*(53)QV00Z74UkUpVIOn=#GwVw%`r5O=y zyZZ)k<#JG#HI+ftYK^OvN~Mw2ZlIrPAQIdxDEw>7UTISPU)x!E8X0JTk*sMNDB6S{ z&1$z_KNVO|fuQzNem_A4MVZqgpoCM>P|WOkLWQEB3I!_?sxYvkp$Y-p4yfG0whJm( zu0S`#j%0q2_=APwc1_I_*r^k_R;{3 z1uSo<0K_n=*D6!+B5lI2)28lWP(G3Zbhivv6jb26s;UbOQ#&)E;0xsZ6<{zj_UNtt zn-Gl72_$dIf$5DjS11ZO$8rAOXl*d3Y1*P;%$(y;Jxm}MDMbGPh8;S!x~l8dOW`)1 zUK(F!oPRM`J^n6NC~B5^;#bp9Uy1i1SrYb`X=-#R1Aiu~uS@fW60H!}wKTrO>4ac( zoaWPk=;^4K?XO$}6rFI~5fep!yIJ!gn5fujXg_n{Cn!D_qYUK@MGy5p9nXGh>N6*! z+Rsup@&@g??jbtAdwkeP5|q%b)%NW3xp$qi;+N?nC(w2Mzsm+2nb?e-qe=ReX3)W9MCPKFW>nA10= zeY*{+2Uf4o{6d+Z#ErNpHowa9b$-28N&n~Pv0~fzPqduXOkXrgiqmuJ5jAE@IPGqw Q8vp(VP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91G@t_j1ONa40RR91Bme*a06kxNfdBvlDM>^@R9Fe^SwUzMK@^=oyV^Es zc9RsP2L<(@f>rBPK`9Cf7V+Ro@Ge;Cp+dnPi+B-1yeM8o#fum9Bq+3q7Y`m3q(~J7 zFCKKen{AUe-I?#7#H3Bg#%_0;Zc7G2X8xaf^WXfLzq@}J+hhgm`M9pTT`;{*qD?Yic-HKG8f09fz9m94Zef54 z`G^728g*)w43Ircr<2#i%m}f>obLjFLJs3eF8bXOupvTTyB1!L@|sg&XG6DPN|<2ae&v$s%?%p45M>7nUadO zM3FIX1Q@#2zH3~u?AcL)LItk#w7Yz5MueoVQWW`XKRZp+v>37ve)=fof1KGfw1~qi z#q=fA)6-=)13}C4wON5|W5x6aX3q4aX^{ zXT|Oy6SbZGbbdOhLartBJs_ay`ye$`<-=xeA$$_TMHHcaOC_)b>z|SD?M+TD;)&Qjdio zbH?67g5kSOMX1N@eg(kqu9Q^lJ*0@Fjjo$ImnSK2_mY~v?_U6z-w=cpsZ=U8MM=oZ zoOvgR(=(zal)R=$nB^FJEq72ZjOeXnU z2M!-8H@D6-mZm2oKP|QVYl%eSCuv9j{i+?gT%3PHX}S1#Nv(Q_!n4_|gPf0$>%0&+ zkqlMI`Y?HIWke|`WKvxdwC&E4r#?qwSwIkVok9=LYhiC5)U?E*wzTrXOG8aXs%gXM hi0s0vmdz$;{RMO#2&9`mnCSoj002ovPDHLkV1lsFrr`hp literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_facing_disable.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_facing_disable.png new file mode 100644 index 0000000000000000000000000000000000000000..dd51ed28e54ec844ab6957dc0bfeb38f8c310e4b GIT binary patch literal 1370 zcmV-g1*Q6lP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91IG_Un1ONa40RR91FaQ7m06ixok^le%#7RU!RA>d|nc1%tMHGkcT-+Bl zhz6rVzy(Z{2reP<>LqG|8biW^KKW<(2l?WwTu4w8(2y8SP7?d2KR>U|+riD?1~3fK5EMe?y z#Q0)p&#d6IGv=!F^c8nqEI2t&gQ3GG(AQL5hi~%?+E+2q41AjB)iH$>Nrro!rHw#` zuLYARf8q3Zz{GSy0vSQbJwW*dFzQg#<~ZaZjJyrWgVT^(Ol1?eQph=haxpP2_Bq-B zCN(5+y;9_~L4wOFhfIFQG6^o7d>)kymbw*4a@6u01`dHE;8*YmP;La~fED20Zk_r>2Se+%|Q z>Km>L1m9eF^$jhlR!}E*;pBO)JAf~%{X~1Wfor<(S#woifsF7BTnPFOQfU>gDF~V< zw&P3|o?QQ?z7?DSF|wS&uR=21mp`KYbc~|%*tP_HMz%uA?(*P-pekc^S*8N3CO zc?eH+C+>q7CFQYg2>M#G0|$OCE6mHZAEmr2uSZwrqnUxxT zQV|R{=P$53(_p(_w+ZVo39Ba@Y4boKrbuD~k#lUS5M71QMJiNq<~WzyEhHP*`(vnY zF6#=1(C5)^-~^V6px-~j1NLs(hItn6=Due^k3jAo8lUUwsA)(=P!ludnP(M!hPDCE zrm?aXU5}P;qV7T5H;X8rqXw4^_9-u+&A-nIf#gvtZvYcStZal-_N;L=gKhy~wrO2=HIvJz3FZ!)Va4Nl z!?>=a3ej=--)KjI;i0zirU@EwN`k{|!jr=Bm<0ENkv!m+c^2ffcbYWq9<=8&J2MLN zd*tR3Dicz<$0$$n(dWI38vZlCehGLNa{KkDAZP`WhOD2~?*QZ4LNJv?&Y|Tea2#?T c0skNJFKMzXA+`rAn*aa+07*qoM6N<$f=+&Qf&c&j literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_facing_enable.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_facing_enable.png new file mode 100644 index 0000000000000000000000000000000000000000..75f014f672efa42c6b9db143b667fd64c204c55e GIT binary patch literal 1381 zcmV-r1)BPaP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91IG_Un1ONa40RR91FaQ7m06ixok^le%&q+id|nO$g9M-<1i#-i1# z)Ksz7D%4OFABq&whk`~_@DuSxY6PPxRH$f*(5h(NCs8OZL%U1<8=4#{g{nrJ@C)WIWu$4`QMp4Gj~%_QRb3z%`cP5 z$may`0jL6fL0IXe<2}%tN~PMv4hrh$j3C7N5NIV>1x5x14cT^$ep?}WGGza}-JB52 z&DstkEY2GxnK2E?-Em#$sk@MRoRor`a@)cKoE$gF#4||nQ3O8&2E&|7D%(0ph%YqZHUlp#5h)`T^P;3R2fDwDKCJ0MqCrUbinO!Ne~zld`RG=o3D z9UvJFbSa+(X61AWXHuydyyeVYVMj-3`qDn5%6q4118(>9sAUp@`Yid11g_=_ie2y4`h0CgY{O{ZZ1p*cu7?>} zk`O!yiQ_>LY5$paEw8Auh*=!t4Z@FR@sy`WDf>q0Z1tT%5t26$j9 z)JIr)9JR_Cbl1{Dsjdjx$AL{aR5Dg49T}#)V=7_mNtUP?!=AAlW@Ci<-}KcFS-PUN z0aGrc=;+Z6NXx$l6ctwlKd~a|kdJdj=vT8dY*_xK!SjplPwGMio7fD`UaWMrL}wCI zJ7!i$Ml%?Agyg!~g*L7x)0f?WHqGAWw!M(f{L}C1pFn>EVg5-2anYlQEKs}_sth{-9`0f;m7bB11c^FRue~re1YUS6n*k& zgNQ0=NKMxuN`0a11@>;O=0I`rHDLzOt!5d-eld+CsGUzYlSM$w>^&gSt~n%I%m3#g z=G9;YsL9_Y*y@^~qCEn2x!KDb9m3j>bXnH}*##nB!59-tTrN>B;2pToy%k)V!+HOm#mztoLUkjBJpc&|}_Abu) z_7kbkfR?HMiA3Fr^b|oS$;NR~igz$h9wi$if^8-9{^}jKiQuJIpGV0uxFmv2K)3jE z6LD(l!xpYHsIlDGiIceL3Y8VkqJ>m+i;sNYd*R`=`Kw<7HbU;OGV%#Zfn+7c$6zAp n4|Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91G@t_j1ONa40RR91EC2ui01YoOKmY&(mq|oHRA>d=n$2odF%-vVY^zpn z)vANFA|fu_h+hjq+=+;S5737Yd={U;tqWbd>B5x=A_Z}4UHCy!u!`DNtK;u~N#eQp zX6~IC>-5G0r%6tdll*heNiw-@wf-||_lu|7?H;7nIxzbEv90l|6Fkm$HK6qLgN83sF_(Gql7X1Qzi}@U>>r)Ac&X?h1bxLaL!x+wW z9?*UnmMd2A&w^fg$~>U#0u`FHTCzZt=%|%B7p?pYA)ubqU0g|wuZ1`cUxyFDBDv~S z_`V7;3ab~X>>%44k&i^AxPxCZ*j@OG8T1rj<+@R-0yG=#F=8R0zB1%fGwcNUlct=@ zRslMkYq_%;McPVs1!#rK#g-ZkA~E` zoW!L#iUDe@h1|XFqX9VQE&)N56d*Ti>vlVl>1iNP4v^b5w(KWEm{oPg0#eId9OVE} z+2r`~FpGe4aa07<*!b~iNOeiIKhM(!#Ky1zpmzpfhfoQ>V2c(?!R3U-x}7it&kBGX zN;W=K3%S*{fF#PSlmPi*{X!ds2ee4#nNfgXLgyLh5*)7l1CFb=I6rUS zRo9>e6|xGDEiup&$`>WvWXisPODALK4d5ocnU~;C=(`67eXq?SeMor)zEY4=9Gavr z8^~$+L8{dp^h>zwo=db)kKspv(dU+oN-M=G>eW=It`6H_-9pNB@WuY|Li+VFdJ-On n*65_$_7Xtsje8hf&F}LYwROTAs0NW@00000NkvXXu0mjfUV`2s literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_mirror_enable_off.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_mirror_enable_off.png new file mode 100644 index 0000000000000000000000000000000000000000..5253e1868e00d20ea76861965145a817181f4f01 GIT binary patch literal 1089 zcmV-H1it%;P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91G@t_j1ONa40RR91EC2ui01YoOKmY&(t4TybRA>d=noDaGK@i8Y8WkUj z8V?#oRH7Ik2_!;5FCuslZ;D{>nv0-*1r;LbC-5wYpk4xg1@$7RNkjwcCBzqMG$G;( z;`;lq)03L#?wZKC=SBEbs)u~z1l0!!=(n2TYZ=8uc%$?h zsZ6_@@KyYLuGS|P5CN>f!ELy&nxmZhJ_32Idi<@Wcm^+#UMEe_z8_zsdHtI6DycgQ z&j*a$htrc_rU7*h+j&@-&!Y`gE;kL-{yP1S;pe@vN5sqw(NT4p9-AXQ>Q^-7#_R3I z_<9fr;mhz&(|-tmdeEtqm-=1wm@k;rL2EG*^elXjw%R~Gm_A1VyUOShF%M8zq-BE? zKut3A4Kw^of0Ql)W*%qGkc|F+;D2SO-=|#RkO2phK!%N88vK+8jDpCNe~$b}Ds_@{!`x zF0p+l0D;2C_2V9H98hA~6%CM`aspWsARjk`N```Sojtkt1cv~Z!PJYEw}67E?fa+| z+l~+oLS)K;c0IO+T^Vd(IdXj3MK*>AAe{KTAvlaSL$XCq3~@ldPd5R04*!x6P_Z+_ z#vm|H9U98rES2yE8_!S?rkt?Y_mRFmbjv6T0R<>K{+hl2YXK?P@O=~l!l(~DGp*Te+l2!Z0I}yfeIo93 zfQq&uxWv44LQu9lK>Dy)MA{w;dddO%607iDWxeR$cH9K|6M4)58Zi}Ki+aVtM+kBV zZZW~$)kfjA>RVKtG?o8NB$(4UKLfA+$3fcYr*GSqCQ+`)5FSPuXb^os#swz(qj4*~ z^(#U+?gEVU1|I`tXH>r2l#_e`z6Ae(7m9RqK}HM6Q>z{_#To`{8Q8f@h64L&Z3JA0V1)i<|xc_`}7KgWobr00000NkvXX Hu0mjfGT+uP literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_mirror_enable_on.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_camera_mirror_enable_on.png new file mode 100644 index 0000000000000000000000000000000000000000..11772fbde684a93a3eec08a431022bc5776c87e0 GIT binary patch literal 1078 zcmV-61j+k}P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91HlPCl1ONa40RR91EC2ui0NE3vhX4Qrph-kQRA>e5n$K@dK@`W|^P4Im ztsfEMR|KVgG!`OZ#e$74B%-mhvhWWGvEz>rQ46sV7DU3%hLEUg+C*6pH1VskAfkRf zpYPLoIi23Q_rB)Ey|;0a(>Z5m&YAO_Gc$MIy)Bg{DV6KRRjE{FW3w6F3b!WMf2aL+ zxm@nE{qWI*-UTPw%d7&whWqgIL=|Z$H86siiNoXY30UCLlECdIs8`MaU){+2oL)zH zm%bomr{kPqYVT85w$juNs*LWp94F)OPu+-QvN0BFGIS&BNDgA@x4s~w)@Jx|Y4 z-4r)?60q%_agV2GsWuFl4vM@iLrv&Bw#tgo%my=tksiVujA4Jq2ZjlyCI+(>1cvDr zcxuf>sr1Omc@f(~fy4o`&o0?N4mruNenJ`R@B+?b#)3zF+KdgezjVXS8?|y4EQ$&$ z5*VGA(0Qpb$YZu#c#&C)1crtG{L170a=;?@SqNAW_Ll<|c`}B8*^KEIY_Ic@!!ljQ z*k5{f*;#nT!SN-BfLut+iFv+LTp5)y-8OXVaFnO}p^M2c$7L-Fm|cc)@E@2zjsH*| zcjPB!>?^_P#Y^5P9vGW&9thSN6ulfAaW893*G$DV#6HJH;AhO=UwOW9_&DrOtdb9` z2se5Q$jW0*Mju#_ZX6brK&Sg#i~+T!P!BH;@i8;6vw+ar7In+35``_3iEu<5Ux1mtu*^ zcQo#YPr;3Pf%5}jZ(&RKtV|D;$RVU0YSU)@$z`?$>g=mC^s|@(k wcEGomVHd1_vzRDp!k)rC_Px# literal 0 HcmV?d00001 diff --git a/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_close_room_icon.png b/scenes_streamerAlone/src/main/resources/base/media/plvsa_more_close_room_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a992226ddf9cc50cceff25baeeb1bd1f6c91e3d3 GIT binary patch literal 1277 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91IG_Un1ONa40RR91FaQ7m06ixok^le%XGugsRA>e5nMa5eK@^5}OqemD zA}Hcv6~lTkU_#c5iU+|35kbAFh+srKDB{6{2f>SiAjn=!7(ow4@ZhRo_F!1oh^}H- z0|pH1_b=^G^iQ%k)cXe0jE-U-TC1vt!Y;0^vy&MbyZOyi3Dt{pE z?NloDIN$hbf{>ezlTDyozRnV~tHt*+h+cDz(L@k(t1(>aYFyy{zlpaHk|$i^rXV*0 zgJYnDi(xbMeMj6%NWKXhU!>-PQXnTzdVOZ95LQI2B5da(={MXZ4-xF|Vo(Hqo$@V} zN7KBo>6zbD29-;ZU=SCpzLizmyvo~zzXWc8yWl-&02;Y2pbZEu#X?Zie>FJ767Vof z_FuEKS)1}9_ytdOKnrgiatbHAAoe*9XMP{91h3#=9?5+4J1W+?>m;+il*s9(yN+O| zLX8w#NKGpJL2nOS%IZBl=0-P4kxN_&t|9PqoN9&(6~Ig&Oj7tCi_Hu$8T2&mjq+>y z>D@ho&l*FYQPgJpMTRyRg_2nu@KbZNUFdL)TO+6u~(JKj#k)F?~VU2Aoa^em_S2AmtUr`t?`mI*b0b zbGe?hk@Fm^;~Ez^xs)&YOiLjM?oLND3XI+?syd6tE%QC!O@5PpMDH_tm3{^!pgpDb zo1Oh_G1avZ8AI%bC?lvBI~Vo@B&_d0Ns&`X`Cg)e>j*x}V`sj3^&%ax#P+kwG`lb~YI$)ktGK#y5evBm2VWtqs8kZy!c^h3oj6BvO7 zKr^h9VADai7>&0We#mD8Eq<)3pmpvQy=|ko9{qZfwK~gFS)b$x_6tZ#YiXh6X_5p7 z2Cz62pie@5CP{*Wc-*>MvObM2*5}X?Ln_5Mog_h>^`Oz9bSykrwQ%MbwCZ80aIC$ zX&~5le>=qW2v>ti{ZVMK8QxmSd>*qgjN!`Ve?D z(1`Z(lF&X@BX*hGUV6Ih7aW}cFMQaZ-KvCIAyxq%7z7Vcc0RTgE9Iv33qoBPx#1am@3R0s$N2z&@+hyVZsu}MThRCt{2oa<2=F%*T*&7=T2i0J?-i0J?-z;pl= zWT}9p0!Rgr3QPyk!EP!r9i04-cH(&KwI0`cIQnLoVLV>lyT|t-OIibsMx)VaG#ZUY zqjAiT>_~RG{WuD&m?K?of2w9f%qD6KJH#Bh&Fx=R>=CmkIomgeB=GYf*qi&d`MQYQ z1di8j8_zNTxDb&cWb7&+Io}pWfn!BS=E!GH!wUe{0Gth2UPR>1^O_`Ni%gP_6QANf z`UChA9if_$>FfM$gqR~|%05L2noUe=yjKuZb;=PVXjU<;0~)+3`xGQ-b}_9JDvdopn@rH@IxvQWbv4$+yO5=EuN=#=MH)Y!7M9C+oluwc7>$pbf zZ$+DziepWZBQjkDeOI*kRdKAH6qn}fkUUdN`IVASJ5xS&ng>C>sS`=g75v#MXl^lG zQy$Pw`$Km7tZAN0P?b*a!GJ_H(?`%>N;U@oDVOpFBy2!F>!Df^dXu=j-UFBg)XsMi z(fUHO9g@q)W~8>_G|`l_ScLfHlkx!YGsKAHNkqO!Twevgg1!dY8IZPaX2VNRTl-!; zZG6Bqg~QgPLhy}Hz(4I%H=(*9dE!ynyWIY!#ydi7>OMKXeefOszl7w>F+zKmun