From 1a7cd941c2a1fb68a55eea81ed2640b9f28f7694 Mon Sep 17 00:00:00 2001 From: reneechai Date: Tue, 12 May 2026 15:46:32 +0800 Subject: [PATCH] [Android][App]Release uikit 4.1.0 application --- application/.gitignore | 3 + application/README.cn.md | 95 ++ application/README.md | 95 ++ application/app/.gitignore | 1 - application/app/build.gradle | 149 ++- application/app/proguard-rules.pro | 37 +- .../uikit/app/ExampleInstrumentedTest.kt | 24 - application/app/src/main/AndroidManifest.xml | 95 +- .../app/src/main/assets/timpush-configs.json | 1 + .../uikit/app/common/utils/GlideEngine.kt | 44 - .../uikit/app/common/utils/ImageUtil.kt | 48 - .../uikit/app/common/utils/LayoutUtil.kt | 15 - .../app/common/utils/SoftKeyBoardUtil.kt | 57 -- .../uikit/app/common/utils/ThreadUtils.kt | 19 - .../app/common/widget/BaseLightActivity.kt | 43 - .../common/widget/ConfirmDialogFragment.kt | 93 -- .../app/common/widget/ITitleBarLayout.kt | 116 --- .../app/common/widget/ImageSelectActivity.kt | 448 --------- .../uikit/app/common/widget/PopupInputCard.kt | 248 ----- .../common/widget/RecycleFragmentNavigator.kt | 139 --- .../app/common/widget/RoundCornerImageView.kt | 121 --- .../app/common/widget/RoundFrameLayout.kt | 121 --- .../uikit/app/common/widget/TitleBarLayout.kt | 155 --- .../app/common/widget/UnreadCountTextView.kt | 84 -- .../widget/gatherimage/MultiImageData.kt | 97 -- .../widget/gatherimage/ShadeImageView.kt | 80 -- .../gatherimage/SynthesizedImageView.kt | 78 -- .../common/widget/gatherimage/Synthesizer.kt | 10 - .../widget/gatherimage/TeamHeadSynthesizer.kt | 470 ---------- .../uikit/app/login/LocalMusicService.kt | 22 - .../tencent/uikit/app/login/LoginActivity.kt | 108 --- .../uikit/app/login/RegisterActivity.kt | 164 ---- .../tencent/uikit/app/main/BaseActivity.kt | 88 -- .../tencent/uikit/app/main/MainActivity.kt | 66 -- .../tencent/uikit/app/main/MainFragment.kt | 145 --- .../tencent/uikit/app/main/MainItemData.kt | 16 - .../tencent/uikit/app/main/MainTypeEnum.kt | 13 - .../tencent/uikit/app/main/TRTCMainAdapter.kt | 146 --- .../tencent/uikit/app/main/TRTCMainData.kt | 31 - .../uikit/app/main/call/GroupCallActivity.kt | 102 -- .../app/main/call/SettingDetailAcitivity.kt | 112 --- .../uikit/app/main/call/SettingsActivity.kt | 431 --------- .../uikit/app/main/live/LiveActivity.kt | 45 - .../uikit/app/main/live/LiveAdapter.kt | 69 -- .../uikit/app/main/live/LiveItemData.kt | 3 - .../uikit/app/main/live/LiveTypeEnum.kt | 8 - .../tencent/uikit/app/mine/MineFragment.kt | 124 --- .../uikit/app/mine/SettingsActivity.kt | 233 ----- .../com/tencent/uikit/app/mine/UserManager.kt | 56 -- .../app/setting/LanguageSelectActivity.kt | 165 ---- .../main/kotlin/com/tencent/rtcube/v2/App.kt | 229 +++++ .../kotlin/com/tencent/rtcube/v2/AppConfig.kt | 27 + .../tencent/rtcube/v2/AppTargetResolver.kt | 19 + .../com/tencent/rtcube/v2/MainActivity.kt | 193 ++++ .../rtcube/v2/component/CommonDialog.kt | 36 + .../v2/component/CommonNavigationBar.kt | 153 +++ .../rtcube/v2/component/ConfirmDialog.kt | 114 +++ .../rtcube/v2/component/ShowTipDialog.kt | 76 ++ .../rtcube/v2/debug/GenerateTestUserSig.kt | 142 +++ .../tencent/rtcube/v2/main/ModuleRegistry.kt | 26 + .../v2/main/common/utils/FileProvider.kt | 3 + .../rtcube/v2/main}/common/utils/FileUtil.kt | 2 +- .../main/domestic/DomesticEntranceScreen.kt | 194 ++++ .../service/ModulePermissionService.kt | 64 ++ .../v2/main/domestic/store/EntranceState.kt | 10 + .../v2/main/domestic/store/EntranceStore.kt | 145 +++ .../v2/main/domestic/views/ModuleCard.kt | 332 +++++++ .../rtcube/v2/main/model/ResolvedModule.kt | 11 + .../main/overseas/OverSeasEntranceScreen.kt | 315 +++++++ .../v2/main/overseas/OverSeasNavHost.kt | 39 + .../v2/main/overseas/store/ContactState.kt | 14 + .../v2/main/overseas/store/ContactStore.kt | 205 ++++ .../overseas/store/OverSeasEntranceState.kt | 10 + .../overseas/store/OverSeasEntranceStore.kt | 122 +++ .../v2/main/overseas/views/ContactScreen.kt | 501 ++++++++++ .../overseas/views/OverSeasDiscoveryCard.kt | 134 +++ .../main/overseas/views/OverSeasModuleCard.kt | 171 ++++ .../tencent/rtcube/v2/mine/MineActivity.kt | 32 + .../com/tencent/rtcube/v2/mine/MineEntry.kt | 25 + .../tencent/rtcube/v2/mine/store/MineState.kt | 16 + .../tencent/rtcube/v2/mine/store/MineStore.kt | 245 +++++ .../tencent/rtcube/v2/mine/ui/AboutScreen.kt | 142 +++ .../rtcube/v2/mine/ui/ExperienceScreen.kt | 745 +++++++++++++++ .../tencent/rtcube/v2/mine/ui/LogOffScreen.kt | 120 +++ .../tencent/rtcube/v2/mine/ui/MineScreen.kt | 381 ++++++++ .../rtcube/v2/mine/ui/SelfDetailScreen.kt | 519 +++++++++++ .../rtcube/v2/privacy/PrivacyActivity.kt | 23 + .../tencent/rtcube/v2/privacy/PrivacyEntry.kt | 38 + .../rtcube/v2/privacy/PrivacyPageType.kt | 9 + .../service/PrivacyBeautyAuthDialog.kt | 98 ++ .../v2/privacy/service/PrivacyService.kt | 36 + .../rtcube/v2/privacy/store/PrivacyState.kt | 14 + .../rtcube/v2/privacy/store/PrivacyStore.kt | 86 ++ .../v2/privacy/ui/PermissionDetailScreen.kt | 121 +++ .../v2/privacy/ui/PersonalAuthScreen.kt | 41 + .../v2/privacy/ui/PersonalInfoDetailScreen.kt | 216 +++++ .../v2/privacy/ui/PersonalInfoScreen.kt | 166 ++++ .../rtcube/v2/privacy/ui/PrivacyComponents.kt | 147 +++ .../rtcube/v2/privacy/ui/PrivacyMainScreen.kt | 64 ++ .../rtcube/v2/privacy/ui/PrivacyScreen.kt | 66 ++ .../rtcube/v2/privacy/ui/SystemAuthScreen.kt | 110 +++ .../com/tencent/rtcube/v2/push/PushManager.kt | 90 ++ .../tencent/rtcube/v2}/utils/KeyMetrics.kt | 4 +- .../drawable-xxhdpi/main_default_avatar.png | Bin 0 -> 17385 bytes .../drawable-xxhdpi/main_english_logo.png} | Bin .../main_entrance_pusharrow.png | Bin 0 -> 455 bytes .../main_entrance_scenarios.png} | Bin .../main_simplified_chinese_logo.png | Bin 0 -> 3165 bytes .../src/main/res-main/values-en/strings.xml | 20 + .../src/main/res-main/values-zh/strings.xml | 20 + .../app/src/main/res-main/values/colors.xml | 20 + .../app/src/main/res-main/values/strings.xml | 20 + .../drawable-xhdpi/mine_profile_ic_back.png | Bin 0 -> 576 bytes .../drawable-xhdpi/mine_profile_ic_close.png} | Bin .../drawable-xhdpi/mine_profile_ic_head.png} | Bin .../drawable-xxhdpi/mine_about_ic_logoff.png | Bin 0 -> 2349 bytes .../mine_experience_ic_blue_scan.png | Bin 0 -> 351 bytes .../mine_experience_ic_copy.png | Bin 0 -> 340 bytes .../mine_experience_ic_down_arrows.png | Bin 0 -> 301 bytes .../mine_experience_ic_get_login_info.png | Bin 0 -> 1054 bytes .../mine_experience_ic_scanner.png | Bin 0 -> 245 bytes .../drawable-xxhdpi/mine_info_bg.png} | Bin .../drawable-xxhdpi/mine_info_ic_about.png | Bin 0 -> 1748 bytes .../drawable-xxhdpi/mine_info_ic_arrow.png} | Bin .../drawable-xxhdpi/mine_info_ic_back.png} | Bin .../drawable-xxhdpi/mine_info_ic_edit.png | Bin 0 -> 470 bytes .../mine_info_ic_fast_debug.png | Bin 0 -> 526 bytes .../drawable-xxhdpi/mine_info_ic_icp.png | Bin 0 -> 756 bytes .../drawable-xxhdpi/mine_info_ic_privacy.png | Bin 0 -> 1124 bytes .../mine_info_ic_statement.png | Bin 0 -> 1152 bytes .../src/main/res-mine/values-en/strings.xml | 74 ++ .../src/main/res-mine/values-ja/strings.xml | 59 ++ .../src/main/res-mine/values-zh/strings.xml | 75 ++ .../app/src/main/res-mine/values/strings.xml | 74 ++ .../overseas_contact_float_button.png | Bin 0 -> 11726 bytes .../overseas_contact_ic_back.png | Bin 0 -> 576 bytes .../main/res-overseas/values-zh/strings.xml | 19 + .../src/main/res-overseas/values/strings.xml | 19 + .../drawable-xhdpi/privacy_ic_back.png | Bin 0 -> 576 bytes .../drawable-xhdpi/privacy_ic_head.png | Bin 0 -> 8604 bytes .../drawable-xxhdpi/privacy_ic_details.png | Bin 0 -> 698 bytes .../main/res-privacy/values-zh/strings.xml | 40 + .../src/main/res-privacy/values/colors.xml | 10 + .../src/main/res-privacy/values/strings.xml | 40 + .../src/main/res/anim/app_popup_in_anim.xml | 8 - .../src/main/res/anim/app_popup_out_anim.xml | 8 - .../main/res/color/app_switch_selector.xml | 5 - .../app/src/main/res/drawable/app_avatar.png | Bin 13676 -> 0 bytes .../app/src/main/res/drawable/app_back.png | Bin 272 -> 0 bytes .../src/main/res/drawable/app_bg_button.xml | 20 - .../res/drawable/app_bg_confirm_dialog.xml | 5 - .../main/res/drawable/app_bg_edit_text.xml | 7 - .../main/res/drawable/app_bg_enter_live.xml | 6 - .../res/drawable/app_bg_main_category_kit.xml | 6 - .../main/res/drawable/app_bg_main_item.xml | 6 - .../res/drawable/app_bg_main_kit_item.xml | 9 - .../main/res/drawable/app_bg_rb_selector.xml | 6 - .../res/drawable/app_core_list_divider.xml | 12 - .../drawable/app_default_user_icon_light.png | Bin 21503 -> 0 bytes .../src/main/res/drawable/app_edit_cursor.xml | 6 - .../main/res/drawable/app_edit_text_bg.xml | 5 - .../main/res/drawable/app_ic_arrow_right.png | Bin 312 -> 0 bytes .../src/main/res/drawable/app_ic_avatar.png | Bin 13676 -> 0 bytes .../main/res/drawable/app_ic_main_call.png | Bin 7883 -> 0 bytes .../main/res/drawable/app_ic_main_live.png | Bin 6753 -> 0 bytes .../res/drawable/app_ic_selected_language.png | Bin 5117 -> 0 bytes .../res/drawable/app_launcher_background.xml | 170 ---- .../res/drawable/app_launcher_foreground.xml | 30 - .../app/src/main/res/drawable/app_log.png | Bin 6379 -> 0 bytes .../main/res/drawable/app_popup_card_bg.xml | 13 - .../main/res/drawable/app_positive_btn_bg.xml | 7 - .../drawable/app_positive_btn_disable_bg.xml | 11 - .../drawable/app_positive_btn_normal_bg.xml | 11 - .../drawable/app_positive_btn_pressed_bg.xml | 11 - .../drawable/app_radio_button_selected.png | Bin 539 -> 0 bytes .../drawable/app_radio_button_unselected.png | Bin 516 -> 0 bytes .../app/src/main/res/drawable/app_right.png | Bin 124 -> 0 bytes .../src/main/res/drawable/app_right_grey.png | Bin 116 -> 0 bytes .../main/res/drawable/app_selected_border.xml | 9 - .../res/drawable/app_selected_icon_light.png | Bin 5117 -> 0 bytes .../src/main/res/drawable/app_settings.png | Bin 8511 -> 0 bytes .../main/res/drawable/app_switch_language.png | Bin 1409 -> 0 bytes .../res/drawable/app_tencent_cloud_logo.png | Bin 4528 -> 0 bytes .../res/drawable/app_title_bar_bg_light.xml | 9 - .../src/main/res/drawable/app_title_zh.png | Bin 6560 -> 0 bytes .../src/main/res/drawable/app_trans_bg.png | Bin 122 -> 0 bytes .../{app_launcher.png => rtcube_launcher.png} | Bin .../res/layout/app_activity_call_simple.xml | 23 - .../res/layout/app_activity_group_call.xml | 241 ----- .../app_activity_image_select_layout.xml | 20 - .../layout/app_activity_language_select.xml | 42 - .../src/main/res/layout/app_activity_live.xml | 138 --- .../main/res/layout/app_activity_login.xml | 86 -- .../res/layout/app_activity_login_profile.xml | 81 -- .../main/res/layout/app_activity_settings.xml | 881 ------------------ .../layout/app_activity_settings_detail.xml | 69 -- .../res/layout/app_activity_trtc_main.xml | 17 - .../main/res/layout/app_adapter_live_item.xml | 58 -- .../main/res/layout/app_dialog_confirm.xml | 74 -- .../src/main/res/layout/app_fragment_main.xml | 53 -- .../main/res/layout/app_fragment_my_info.xml | 188 ---- .../src/main/res/layout/app_item_settings.xml | 42 - .../src/main/res/layout/app_item_web_view.xml | 54 -- .../main/res/layout/app_layout_popup_card.xml | 83 -- .../main/res/layout/app_layout_title_bar.xml | 94 -- .../layout/app_login_select_item_layout.xml | 30 - .../app/src/main/res/layout/app_main_item.xml | 50 - .../src/main/res/layout/app_mine_settings.xml | 51 - .../layout/app_select_image_item_layout.xml | 59 -- .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 - .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 1404 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 2898 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 982 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 1772 -> 0 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 1900 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 3918 -> 0 bytes .../res/mipmap-xxhdpi/app_ic_enter_live.png | Bin 278 -> 0 bytes .../mipmap-xxhdpi/app_item_bg_live_stream.png | Bin 129252 -> 0 bytes .../mipmap-xxhdpi/app_item_bg_voice_room.png | Bin 129252 -> 0 bytes .../app_item_live_stream_end_bg.png | Bin 155623 -> 0 bytes .../app_item_voice_room_end_bg.png | Bin 85556 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 2884 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 5914 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 3844 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 7778 -> 0 bytes .../res/navigation/app_nav_main_graph.xml | 19 - .../app/src/main/res/values-en/strings.xml | 110 +-- .../app/src/main/res/values-ja/strings.xml | 107 +-- .../app/src/main/res/values-night/themes.xml | 7 - .../app/src/main/res/values-zh/strings.xml | 115 +-- .../app/src/main/res/values/arrays.xml | 31 - application/app/src/main/res/values/attrs.xml | 38 - .../app/src/main/res/values/colors.xml | 33 +- .../app/src/main/res/values/dimens.xml | 18 - .../app/src/main/res/values/strings.xml | 116 +-- .../app/src/main/res/values/styles.xml | 32 - .../app/src/main/res/values/themes.xml | 25 +- .../app/src/main/res/xml/backup_rules.xml | 13 - .../main/res/xml/data_extraction_rules.xml | 19 - .../app/src/main/res/xml/file_paths.xml | 6 + .../app/src/main/res/xml/filepaths.xml | 4 - .../com/tencent/uikit/app/ExampleUnitTest.kt | 17 - application/app/trtc.keystore | Bin 0 -> 4285 bytes application/assembly/build.gradle | 105 +++ application/assembly/consumer-rules.pro | 6 + .../assembly/src/main/AndroidManifest.xml | 31 + .../tencent/rtcube/assembly/AppAssembly.kt | 80 ++ .../com/tencent/rtcube/assembly/CallGuard.kt | 16 + .../rtcube/assembly/EntranceCardStyle.kt | 7 + .../tencent/rtcube/assembly/ModuleConfig.kt | 30 + .../rtcube/assembly/ModuleEnvironment.kt | 33 + .../tencent/rtcube/assembly/ModuleProvider.kt | 34 + .../rtcube/modules/call/CallActivity.kt | 30 + .../tencent/rtcube/modules/call/CallModule.kt | 67 ++ .../modules/call/lab/LabCallEntrance.kt | 61 ++ .../call/lab/store/LabSettingsState.kt | 31 + .../call/lab/store/LabSettingsStore.kt | 152 +++ .../modules/call/lab/ui/LabCallScreen.kt | 377 ++++++++ .../call/lab/ui/LabCustomUIAdapter.kt} | 33 +- .../call/lab/ui/LabSettingDetailScreen.kt | 221 +++++ .../modules/call/lab/ui/LabSettingsConfig.kt} | 8 +- .../modules/call/lab/ui/LabSettingsScreen.kt | 732 +++++++++++++++ .../modules/call/online/CallEntrance.kt | 160 ++++ .../call/online/guide/GuideHomeScreen.kt | 116 +++ .../modules/call/online/guide/GuideModel.kt | 28 + .../modules/call/online/guide/GuideScreen.kt | 250 +++++ .../call/online/guide/GuideStepItem.kt | 167 ++++ .../call/online/model/CallingMenuModel.kt | 6 + .../online/model/CallingRequestRobotModel.kt | 19 + .../call/online/model/CallingRobotModel.kt | 16 + .../online/service/HttpRequestBotService.kt | 163 ++++ .../modules/call/online/ui/CallTitleBar.kt | 61 ++ .../online/ui/CallingBotHesitationScreen.kt | 232 +++++ .../call/online/ui/CallingContactScreen.kt | 411 ++++++++ .../online/ui/CallingEntranceMenuScreen.kt | 283 ++++++ .../online/ui/CallingRecentCallsScreen.kt | 67 ++ .../call/service/CallAntifraudHandler.kt | 35 + .../rtcube/modules/live/LiveListActivity.kt | 89 ++ .../tencent/rtcube/modules/live/LiveModule.kt | 64 ++ .../live/service/LiveTimeLimitHandler.kt | 58 ++ .../rtcube/modules/live/ui/LiveListScreen.kt | 196 ++++ .../tencent/rtcube/modules/room/RoomModule.kt | 55 ++ .../ScenesApplicationModule.kt | 52 ++ .../voiceroom/VoiceRoomListActivity.kt | 291 ++++++ .../modules/voiceroom/VoiceRoomModule.kt | 51 + .../tencent/rtcube/utils/PackageService.kt | 20 + .../drawable/call_common_ic_arrow_right.png | Bin 0 -> 646 bytes .../res-call/drawable/call_common_ic_back.png | Bin 0 -> 576 bytes .../drawable/call_contact_ic_clear.png | Bin 0 -> 4385 bytes .../call_contact_ic_default_avatar.png | Bin 0 -> 62337 bytes .../drawable/call_contact_ic_guidance.png | Bin 0 -> 45209 bytes .../drawable/call_contact_ic_search.png | Bin 0 -> 1242 bytes .../res-call/drawable/call_guide_app_call.png | Bin 0 -> 28413 bytes .../drawable/call_guide_app_call_en.png | Bin 0 -> 26814 bytes .../drawable/call_guide_app_download.png | Bin 0 -> 80098 bytes .../drawable/call_guide_app_download_en.png | Bin 0 -> 69365 bytes .../drawable/call_guide_app_login.png | Bin 0 -> 79623 bytes .../drawable/call_guide_app_login_en.png | Bin 0 -> 51178 bytes .../drawable/call_guide_app_userid.png | Bin 0 -> 31214 bytes .../drawable/call_guide_app_userid_en.png | Bin 0 -> 29531 bytes .../drawable/call_guide_avatar_friend.png | Bin 0 -> 9284 bytes .../drawable/call_guide_avatar_pc.png | Bin 0 -> 1413 bytes .../drawable/call_guide_avatar_phone.png | Bin 0 -> 1168 bytes .../drawable/call_guide_avatar_self.png | Bin 0 -> 10255 bytes .../drawable/call_guide_web_login.png | Bin 0 -> 106720 bytes .../drawable/call_guide_web_login_en.png | Bin 0 -> 116069 bytes .../drawable/call_guide_web_open_call.png | Bin 0 -> 160525 bytes .../drawable/call_guide_web_userid.png | Bin 0 -> 95517 bytes .../drawable/call_guide_web_userid_en.png | Bin 0 -> 105416 bytes .../drawable/call_menu_ic_arrow_down.png | Bin 0 -> 596 bytes .../drawable/call_menu_ic_robot_a.png | Bin 0 -> 6847 bytes .../drawable/call_menu_ic_robot_b.png | Bin 0 -> 6392 bytes .../drawable/call_menu_ic_robot_call.png | Bin 0 -> 1852 bytes .../drawable/call_menu_ic_robot_called.png | Bin 0 -> 1876 bytes .../res-call/raw/call_guide_single_data.json | 50 + .../raw/call_guide_with_app_data.json | 50 + .../raw/call_guide_with_web_data.json | 50 + .../src/main/res-call/values-en/strings.xml | 104 +++ .../src/main/res-call/values-zh/strings.xml | 104 +++ .../src/main/res-call/values/colors.xml | 17 + .../src/main/res-call/values/strings.xml | 104 +++ .../drawable-xxhdpi/live_list_ic_back.png | Bin 0 -> 537 bytes .../live_list_ic_create_live.png | Bin 0 -> 221 bytes .../live_list_ic_double_column.png | Bin 0 -> 385 bytes .../live_list_ic_single_column.png | Bin 0 -> 309 bytes .../src/main/res-live/values-en/strings.xml | 12 + .../src/main/res-live/values-zh/strings.xml | 12 + .../src/main/res-live/values/strings.xml | 11 + .../src/main/res-room/values-en/strings.xml | 6 + .../src/main/res-room/values-zh/strings.xml | 6 + .../src/main/res-room/values/strings.xml | 5 + .../values-en/strings.xml | 5 + .../values-zh/strings.xml | 5 + .../res-scenes-application/values/strings.xml | 5 + .../drawable-xxhdpi/voice_room_ic_back.png | Bin 0 -> 537 bytes .../drawable-xxhdpi/voice_room_ic_create.png | Bin 0 -> 221 bytes .../main/res-voiceroom/values-en/strings.xml | 7 + .../main/res-voiceroom/values-zh/strings.xml | 7 + .../src/main/res-voiceroom/values/strings.xml | 6 + .../main/res/drawable/module_ic_beauty.png | Bin 0 -> 7440 bytes .../src/main/res/drawable/module_ic_call.png | Bin 0 -> 7971 bytes .../src/main/res/drawable/module_ic_chat.png | Bin 0 -> 6808 bytes .../src/main/res/drawable/module_ic_live.png | Bin 0 -> 6755 bytes .../main/res/drawable/module_ic_player.png | Bin 0 -> 6424 bytes .../src/main/res/drawable/module_ic_room.png} | Bin .../src/main/res/drawable/module_ic_ugsv.png | Bin 0 -> 8083 bytes .../res/drawable/module_ic_voiceroom.png} | Bin .../src/main/res/values-en/strings.xml | 4 + .../src/main/res/values-zh/strings.xml | 4 + .../assembly/src/main/res/values/strings.xml | 4 + application/build.gradle | 61 +- application/debug/.gitignore | 1 - application/debug/build.gradle | 29 - application/debug/consumer-rules.pro | 0 .../tuikit/debug/GenerateTestUserSig.java | 202 ---- application/gradle.properties | 46 +- application/gradle/libs.versions.toml | 138 +-- application/gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 54329 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 +- application/gradlew | 211 ++--- application/gradlew.bat | 89 -- application/login/build.gradle | 103 ++ application/login/consumer-rules.pro | 4 + .../login/src/main/AndroidManifest.xml | 37 + .../rtcube/v2/login/AgreementNavigator.kt | 39 + .../tencent/rtcube/v2/login/LoginActivity.kt | 69 ++ .../tencent/rtcube/v2/login/LoginConfig.kt | 43 + .../com/tencent/rtcube/v2/login/LoginEntry.kt | 416 +++++++++ .../com/tencent/rtcube/v2/login/LoginMode.kt | 11 + .../tencent/rtcube/v2/login/LoginNavHost.kt | 513 ++++++++++ .../tencent/rtcube/v2/login/LoginSubStore.kt | 12 + .../tencent/rtcube/v2/login/LoginViewModel.kt | 42 + .../rtcube/v2/login/LoginWebViewActivity.kt | 230 +++++ .../rtcube/v2/login/ServerEnvironment.kt | 9 + .../v2/login/components/model/AvatarModel.kt | 9 + .../v2/login/components/model/LoginError.kt | 27 + .../v2/login/components/model/LoginResult.kt | 8 + .../v2/login/components/model/UserModel.kt | 28 + .../components/service/CaptchaService.kt | 296 ++++++ .../login/components/service/LoginManager.kt | 357 +++++++ .../components/service/LoginNetworkService.kt | 609 ++++++++++++ .../login/components/service/LoginService.kt | 61 ++ .../service/TUILoginListenerHandler.kt | 32 + .../login/components/views/AgreementView.kt | 206 ++++ .../login/components/views/CountdownButton.kt | 56 ++ .../components/views/InviteCodeInputField.kt | 133 +++ .../login/components/views/LoginComponents.kt | 253 +++++ .../components/views/LoginExtraComponents.kt | 124 +++ .../components/views/PrivacyBottomDialog.kt | 121 +++ .../v2/login/debugauth/DebugAuthScreen.kt | 136 +++ .../login/debugauth/store/DebugAuthState.kt | 9 + .../login/debugauth/store/DebugAuthStore.kt | 129 +++ .../rtcube/v2/login/devmenu/DevMenuScreen.kt | 291 ++++++ .../emailverify/EmailInviteCodeScreen.kt | 241 +++++ .../v2/login/emailverify/EmailVerifyScreen.kt | 256 +++++ .../emailverify/store/EmailInviteCodeState.kt | 18 + .../emailverify/store/EmailInviteCodeStore.kt | 156 ++++ .../emailverify/store/EmailVerifyState.kt | 17 + .../emailverify/store/EmailVerifyStore.kt | 303 ++++++ .../hiddenconfig/HiddenConfigCredentials.kt | 9 + .../login/hiddenconfig/HiddenConfigScreen.kt | 213 +++++ .../v2/login/hiddenconfig/QRCodeScanScreen.kt | 218 +++++ .../hiddenconfig/store/HiddenConfigState.kt | 8 + .../hiddenconfig/store/HiddenConfigStore.kt | 65 ++ .../v2/login/invitecode/InviteCodeScreen.kt | 203 ++++ .../login/invitecode/store/InviteCodeState.kt | 11 + .../login/invitecode/store/InviteCodeStore.kt | 88 ++ .../invitecode/utils/InviteCodeValidator.kt | 8 + .../rtcube/v2/login/ioaauth/IOAAuthScreen.kt | 94 ++ .../v2/login/ioaauth/store/IOAAuthState.kt | 6 + .../v2/login/ioaauth/store/IOAAuthStore.kt | 140 +++ .../v2/login/phoneverify/PhoneVerifyScreen.kt | 284 ++++++ .../phoneverify/store/PhoneVerifyState.kt | 16 + .../phoneverify/store/PhoneVerifyStore.kt | 322 +++++++ .../v2/login/profile/AvatarSelectDialog.kt | 138 +++ .../rtcube/v2/login/profile/ProfileScreen.kt | 160 ++++ .../v2/login/profile/store/AvatarConstants.kt | 7 + .../v2/login/profile/store/ProfileState.kt | 12 + .../v2/login/profile/store/ProfileStore.kt | 131 +++ .../login/tokenauth/store/TokenAuthStore.kt | 35 + .../tokenauth/utils/TokenCacheManager.kt | 51 + .../res/drawable-xhdpi/login_bg_login_top.png | Bin 0 -> 84903 bytes .../res/drawable-xhdpi/login_ic_cb_normal.png | Bin 0 -> 451 bytes .../res/drawable-xhdpi/login_ic_cb_select.png | Bin 0 -> 746 bytes .../main/res/drawable-xhdpi/login_ic_head.png | Bin 0 -> 8604 bytes .../res/drawable-xhdpi/login_ic_phone.png | Bin 0 -> 325 bytes .../main/res/drawable-xhdpi/login_ic_safe.png | Bin 0 -> 1071 bytes .../res/drawable-xhdpi/login_title_app.png | Bin 0 -> 14436 bytes .../login_email_invite_back.png} | Bin .../login_email_welcome_bg.png | Bin 0 -> 281888 bytes .../login_email_welcome_logo.png | Bin 0 -> 1944 bytes .../drawable-xxhdpi/login_ic_cb_normal.png | Bin 0 -> 540 bytes .../drawable-xxhdpi/login_ic_cb_select.png | Bin 0 -> 873 bytes .../login_ic_full_screen_background.png | Bin 0 -> 281888 bytes .../main/res/drawable-xxhdpi/login_ic_ioa.png | Bin 0 -> 3089 bytes .../drawable-xxhdpi/login_ic_menu_debug.png | Bin 0 -> 4668 bytes .../drawable-xxhdpi/login_ic_menu_email.png | Bin 0 -> 2730 bytes .../drawable-xxhdpi/login_ic_menu_invite.png | Bin 0 -> 1582 bytes .../res/drawable-xxhdpi/login_ic_menu_ioa.png | Bin 0 -> 1906 bytes .../drawable-xxhdpi/login_ic_menu_phone.png | Bin 0 -> 1635 bytes .../res/drawable-xxhdpi/login_ic_phone.png | Bin 0 -> 357 bytes .../res/drawable-xxhdpi/login_ic_qrcode.png | Bin 0 -> 3356 bytes .../res/drawable-xxhdpi/login_ic_safe.png | Bin 0 -> 1319 bytes .../res/drawable-xxhdpi/login_ic_sdkappid.png | Bin 0 -> 1009 bytes .../res/drawable-xxhdpi/login_ic_user_id.png | Bin 0 -> 818 bytes .../res/drawable-xxhdpi/login_ic_user_sig.png | Bin 0 -> 1054 bytes .../drawable-xxhdpi/login_title_bar_back.png} | Bin .../drawable/login_bg_terms_tooltip_arrow.xml | 16 + .../res/drawable/login_ic_arrow_right.xml | 11 + .../login/src/main/res/values-en/strings.xml | 149 +++ .../login/src/main/res/values-zh/strings.xml | 146 +++ .../login/src/main/res/values/colors.xml | 18 + .../login/src/main/res/values/strings.xml | 147 +++ application/settings.gradle | 36 +- 455 files changed, 21651 insertions(+), 8799 deletions(-) create mode 100644 application/README.cn.md create mode 100644 application/README.md delete mode 100644 application/app/.gitignore delete mode 100644 application/app/src/androidTest/java/com/tencent/uikit/app/ExampleInstrumentedTest.kt create mode 100644 application/app/src/main/assets/timpush-configs.json delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/utils/GlideEngine.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/utils/ImageUtil.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/utils/LayoutUtil.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/utils/SoftKeyBoardUtil.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/utils/ThreadUtils.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/BaseLightActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/ConfirmDialogFragment.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/ITitleBarLayout.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/ImageSelectActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/PopupInputCard.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/RecycleFragmentNavigator.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundCornerImageView.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundFrameLayout.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/TitleBarLayout.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/UnreadCountTextView.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/MultiImageData.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/ShadeImageView.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/SynthesizedImageView.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/Synthesizer.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/TeamHeadSynthesizer.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/login/LocalMusicService.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/login/LoginActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/login/RegisterActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/BaseActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/MainActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/MainFragment.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/MainItemData.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/MainTypeEnum.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainAdapter.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainData.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/call/GroupCallActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/call/SettingDetailAcitivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/call/SettingsActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/live/LiveActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/live/LiveAdapter.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/live/LiveItemData.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/main/live/LiveTypeEnum.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/mine/MineFragment.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/mine/SettingsActivity.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/mine/UserManager.kt delete mode 100644 application/app/src/main/java/com/tencent/uikit/app/setting/LanguageSelectActivity.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/App.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/AppConfig.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/AppTargetResolver.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/MainActivity.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/component/CommonDialog.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/component/CommonNavigationBar.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/component/ConfirmDialog.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/component/ShowTipDialog.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/debug/GenerateTestUserSig.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/ModuleRegistry.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/common/utils/FileProvider.kt rename application/app/src/main/{java/com/tencent/uikit/app => kotlin/com/tencent/rtcube/v2/main}/common/utils/FileUtil.kt (98%) create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/domestic/DomesticEntranceScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/domestic/service/ModulePermissionService.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/domestic/store/EntranceState.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/domestic/store/EntranceStore.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/domestic/views/ModuleCard.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/model/ResolvedModule.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/OverSeasEntranceScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/OverSeasNavHost.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/store/ContactState.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/store/ContactStore.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/store/OverSeasEntranceState.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/store/OverSeasEntranceStore.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/views/ContactScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/views/OverSeasDiscoveryCard.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/main/overseas/views/OverSeasModuleCard.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/MineActivity.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/MineEntry.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/store/MineState.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/store/MineStore.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/ui/AboutScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/ui/ExperienceScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/ui/LogOffScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/ui/MineScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/mine/ui/SelfDetailScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/PrivacyActivity.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/PrivacyEntry.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/PrivacyPageType.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/service/PrivacyBeautyAuthDialog.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/service/PrivacyService.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/store/PrivacyState.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/store/PrivacyStore.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/PermissionDetailScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/PersonalAuthScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/PersonalInfoDetailScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/PersonalInfoScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/PrivacyComponents.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/PrivacyMainScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/PrivacyScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/privacy/ui/SystemAuthScreen.kt create mode 100644 application/app/src/main/kotlin/com/tencent/rtcube/v2/push/PushManager.kt rename application/app/src/main/{java/com/tencent/uikit/app/common => kotlin/com/tencent/rtcube/v2}/utils/KeyMetrics.kt (95%) create mode 100644 application/app/src/main/res-main/drawable-xxhdpi/main_default_avatar.png rename application/app/src/main/{res/drawable/app_title_en.png => res-main/drawable-xxhdpi/main_english_logo.png} (100%) create mode 100644 application/app/src/main/res-main/drawable-xxhdpi/main_entrance_pusharrow.png rename application/app/src/main/{res/drawable/app_bg_entrance_scenarios.png => res-main/drawable-xxhdpi/main_entrance_scenarios.png} (100%) create mode 100644 application/app/src/main/res-main/drawable-xxhdpi/main_simplified_chinese_logo.png create mode 100644 application/app/src/main/res-main/values-en/strings.xml create mode 100644 application/app/src/main/res-main/values-zh/strings.xml create mode 100644 application/app/src/main/res-main/values/colors.xml create mode 100644 application/app/src/main/res-main/values/strings.xml create mode 100644 application/app/src/main/res-mine/drawable-xhdpi/mine_profile_ic_back.png rename application/app/src/main/{res/drawable/app_close_icon.png => res-mine/drawable-xhdpi/mine_profile_ic_close.png} (100%) rename application/app/src/main/{res/drawable/app_ic_head.png => res-mine/drawable-xhdpi/mine_profile_ic_head.png} (100%) create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_about_ic_logoff.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_experience_ic_blue_scan.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_experience_ic_copy.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_experience_ic_down_arrows.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_experience_ic_get_login_info.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_experience_ic_scanner.png rename application/app/src/main/{res/drawable/app_my_info_bg.png => res-mine/drawable-xxhdpi/mine_info_bg.png} (100%) create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_info_ic_about.png rename application/app/src/main/{res/drawable/app_ic_details.png => res-mine/drawable-xxhdpi/mine_info_ic_arrow.png} (100%) rename application/app/src/main/{res/drawable/app_ic_back_with_line.png => res-mine/drawable-xxhdpi/mine_info_ic_back.png} (100%) create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_info_ic_edit.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_info_ic_fast_debug.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_info_ic_icp.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_info_ic_privacy.png create mode 100644 application/app/src/main/res-mine/drawable-xxhdpi/mine_info_ic_statement.png create mode 100644 application/app/src/main/res-mine/values-en/strings.xml create mode 100644 application/app/src/main/res-mine/values-ja/strings.xml create mode 100644 application/app/src/main/res-mine/values-zh/strings.xml create mode 100644 application/app/src/main/res-mine/values/strings.xml create mode 100644 application/app/src/main/res-overseas/drawable-xhdpi/overseas_contact_float_button.png create mode 100644 application/app/src/main/res-overseas/drawable-xhdpi/overseas_contact_ic_back.png create mode 100644 application/app/src/main/res-overseas/values-zh/strings.xml create mode 100644 application/app/src/main/res-overseas/values/strings.xml create mode 100644 application/app/src/main/res-privacy/drawable-xhdpi/privacy_ic_back.png create mode 100755 application/app/src/main/res-privacy/drawable-xhdpi/privacy_ic_head.png create mode 100644 application/app/src/main/res-privacy/drawable-xxhdpi/privacy_ic_details.png create mode 100644 application/app/src/main/res-privacy/values-zh/strings.xml create mode 100644 application/app/src/main/res-privacy/values/colors.xml create mode 100644 application/app/src/main/res-privacy/values/strings.xml delete mode 100644 application/app/src/main/res/anim/app_popup_in_anim.xml delete mode 100644 application/app/src/main/res/anim/app_popup_out_anim.xml delete mode 100644 application/app/src/main/res/color/app_switch_selector.xml delete mode 100644 application/app/src/main/res/drawable/app_avatar.png delete mode 100644 application/app/src/main/res/drawable/app_back.png delete mode 100644 application/app/src/main/res/drawable/app_bg_button.xml delete mode 100644 application/app/src/main/res/drawable/app_bg_confirm_dialog.xml delete mode 100644 application/app/src/main/res/drawable/app_bg_edit_text.xml delete mode 100644 application/app/src/main/res/drawable/app_bg_enter_live.xml delete mode 100644 application/app/src/main/res/drawable/app_bg_main_category_kit.xml delete mode 100644 application/app/src/main/res/drawable/app_bg_main_item.xml delete mode 100644 application/app/src/main/res/drawable/app_bg_main_kit_item.xml delete mode 100644 application/app/src/main/res/drawable/app_bg_rb_selector.xml delete mode 100644 application/app/src/main/res/drawable/app_core_list_divider.xml delete mode 100644 application/app/src/main/res/drawable/app_default_user_icon_light.png delete mode 100644 application/app/src/main/res/drawable/app_edit_cursor.xml delete mode 100644 application/app/src/main/res/drawable/app_edit_text_bg.xml delete mode 100644 application/app/src/main/res/drawable/app_ic_arrow_right.png delete mode 100644 application/app/src/main/res/drawable/app_ic_avatar.png delete mode 100644 application/app/src/main/res/drawable/app_ic_main_call.png delete mode 100644 application/app/src/main/res/drawable/app_ic_main_live.png delete mode 100644 application/app/src/main/res/drawable/app_ic_selected_language.png delete mode 100644 application/app/src/main/res/drawable/app_launcher_background.xml delete mode 100644 application/app/src/main/res/drawable/app_launcher_foreground.xml delete mode 100644 application/app/src/main/res/drawable/app_log.png delete mode 100644 application/app/src/main/res/drawable/app_popup_card_bg.xml delete mode 100644 application/app/src/main/res/drawable/app_positive_btn_bg.xml delete mode 100644 application/app/src/main/res/drawable/app_positive_btn_disable_bg.xml delete mode 100644 application/app/src/main/res/drawable/app_positive_btn_normal_bg.xml delete mode 100644 application/app/src/main/res/drawable/app_positive_btn_pressed_bg.xml delete mode 100644 application/app/src/main/res/drawable/app_radio_button_selected.png delete mode 100644 application/app/src/main/res/drawable/app_radio_button_unselected.png delete mode 100644 application/app/src/main/res/drawable/app_right.png delete mode 100644 application/app/src/main/res/drawable/app_right_grey.png delete mode 100644 application/app/src/main/res/drawable/app_selected_border.xml delete mode 100644 application/app/src/main/res/drawable/app_selected_icon_light.png delete mode 100644 application/app/src/main/res/drawable/app_settings.png delete mode 100644 application/app/src/main/res/drawable/app_switch_language.png delete mode 100644 application/app/src/main/res/drawable/app_tencent_cloud_logo.png delete mode 100644 application/app/src/main/res/drawable/app_title_bar_bg_light.xml delete mode 100644 application/app/src/main/res/drawable/app_title_zh.png delete mode 100755 application/app/src/main/res/drawable/app_trans_bg.png rename application/app/src/main/res/drawable/{app_launcher.png => rtcube_launcher.png} (100%) delete mode 100644 application/app/src/main/res/layout/app_activity_call_simple.xml delete mode 100644 application/app/src/main/res/layout/app_activity_group_call.xml delete mode 100644 application/app/src/main/res/layout/app_activity_image_select_layout.xml delete mode 100644 application/app/src/main/res/layout/app_activity_language_select.xml delete mode 100644 application/app/src/main/res/layout/app_activity_live.xml delete mode 100644 application/app/src/main/res/layout/app_activity_login.xml delete mode 100644 application/app/src/main/res/layout/app_activity_login_profile.xml delete mode 100644 application/app/src/main/res/layout/app_activity_settings.xml delete mode 100644 application/app/src/main/res/layout/app_activity_settings_detail.xml delete mode 100644 application/app/src/main/res/layout/app_activity_trtc_main.xml delete mode 100644 application/app/src/main/res/layout/app_adapter_live_item.xml delete mode 100644 application/app/src/main/res/layout/app_dialog_confirm.xml delete mode 100644 application/app/src/main/res/layout/app_fragment_main.xml delete mode 100644 application/app/src/main/res/layout/app_fragment_my_info.xml delete mode 100644 application/app/src/main/res/layout/app_item_settings.xml delete mode 100644 application/app/src/main/res/layout/app_item_web_view.xml delete mode 100644 application/app/src/main/res/layout/app_layout_popup_card.xml delete mode 100644 application/app/src/main/res/layout/app_layout_title_bar.xml delete mode 100644 application/app/src/main/res/layout/app_login_select_item_layout.xml delete mode 100644 application/app/src/main/res/layout/app_main_item.xml delete mode 100644 application/app/src/main/res/layout/app_mine_settings.xml delete mode 100644 application/app/src/main/res/layout/app_select_image_item_layout.xml delete mode 100644 application/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 application/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 application/app/src/main/res/mipmap-hdpi/ic_launcher.webp delete mode 100644 application/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp delete mode 100644 application/app/src/main/res/mipmap-mdpi/ic_launcher.webp delete mode 100644 application/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 application/app/src/main/res/mipmap-xhdpi/ic_launcher.webp delete mode 100644 application/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp delete mode 100644 application/app/src/main/res/mipmap-xxhdpi/app_ic_enter_live.png delete mode 100644 application/app/src/main/res/mipmap-xxhdpi/app_item_bg_live_stream.png delete mode 100644 application/app/src/main/res/mipmap-xxhdpi/app_item_bg_voice_room.png delete mode 100644 application/app/src/main/res/mipmap-xxhdpi/app_item_live_stream_end_bg.png delete mode 100644 application/app/src/main/res/mipmap-xxhdpi/app_item_voice_room_end_bg.png delete mode 100644 application/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp delete mode 100644 application/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp delete mode 100644 application/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp delete mode 100644 application/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp delete mode 100644 application/app/src/main/res/navigation/app_nav_main_graph.xml delete mode 100644 application/app/src/main/res/values-night/themes.xml delete mode 100644 application/app/src/main/res/values/arrays.xml delete mode 100644 application/app/src/main/res/values/attrs.xml delete mode 100644 application/app/src/main/res/values/dimens.xml delete mode 100644 application/app/src/main/res/values/styles.xml delete mode 100644 application/app/src/main/res/xml/backup_rules.xml delete mode 100644 application/app/src/main/res/xml/data_extraction_rules.xml create mode 100644 application/app/src/main/res/xml/file_paths.xml delete mode 100644 application/app/src/main/res/xml/filepaths.xml delete mode 100644 application/app/src/test/java/com/tencent/uikit/app/ExampleUnitTest.kt create mode 100644 application/app/trtc.keystore create mode 100644 application/assembly/build.gradle create mode 100644 application/assembly/consumer-rules.pro create mode 100644 application/assembly/src/main/AndroidManifest.xml create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/assembly/AppAssembly.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/assembly/CallGuard.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/assembly/EntranceCardStyle.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/assembly/ModuleConfig.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/assembly/ModuleEnvironment.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/assembly/ModuleProvider.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/CallActivity.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/CallModule.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/lab/LabCallEntrance.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/lab/store/LabSettingsState.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/lab/store/LabSettingsStore.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/lab/ui/LabCallScreen.kt rename application/{app/src/main/java/com/tencent/uikit/app/main/call/CustomUIAdapter.kt => assembly/src/main/java/com/tencent/rtcube/modules/call/lab/ui/LabCustomUIAdapter.kt} (63%) create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/lab/ui/LabSettingDetailScreen.kt rename application/{app/src/main/java/com/tencent/uikit/app/main/call/SettingsConfig.kt => assembly/src/main/java/com/tencent/rtcube/modules/call/lab/ui/LabSettingsConfig.kt} (89%) create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/lab/ui/LabSettingsScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/CallEntrance.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/guide/GuideHomeScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/guide/GuideModel.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/guide/GuideScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/guide/GuideStepItem.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/model/CallingMenuModel.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/model/CallingRequestRobotModel.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/model/CallingRobotModel.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/service/HttpRequestBotService.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/ui/CallTitleBar.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/ui/CallingBotHesitationScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/ui/CallingContactScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/ui/CallingEntranceMenuScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/online/ui/CallingRecentCallsScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/call/service/CallAntifraudHandler.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/live/LiveListActivity.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/live/LiveModule.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/live/service/LiveTimeLimitHandler.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/live/ui/LiveListScreen.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/room/RoomModule.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/scenesapplication/ScenesApplicationModule.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/voiceroom/VoiceRoomListActivity.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/modules/voiceroom/VoiceRoomModule.kt create mode 100644 application/assembly/src/main/java/com/tencent/rtcube/utils/PackageService.kt create mode 100644 application/assembly/src/main/res-call/drawable/call_common_ic_arrow_right.png create mode 100644 application/assembly/src/main/res-call/drawable/call_common_ic_back.png create mode 100644 application/assembly/src/main/res-call/drawable/call_contact_ic_clear.png create mode 100644 application/assembly/src/main/res-call/drawable/call_contact_ic_default_avatar.png create mode 100644 application/assembly/src/main/res-call/drawable/call_contact_ic_guidance.png create mode 100644 application/assembly/src/main/res-call/drawable/call_contact_ic_search.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_call.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_call_en.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_download.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_download_en.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_login.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_login_en.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_userid.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_app_userid_en.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_avatar_friend.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_avatar_pc.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_avatar_phone.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_avatar_self.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_web_login.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_web_login_en.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_web_open_call.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_web_userid.png create mode 100644 application/assembly/src/main/res-call/drawable/call_guide_web_userid_en.png create mode 100644 application/assembly/src/main/res-call/drawable/call_menu_ic_arrow_down.png create mode 100644 application/assembly/src/main/res-call/drawable/call_menu_ic_robot_a.png create mode 100644 application/assembly/src/main/res-call/drawable/call_menu_ic_robot_b.png create mode 100644 application/assembly/src/main/res-call/drawable/call_menu_ic_robot_call.png create mode 100644 application/assembly/src/main/res-call/drawable/call_menu_ic_robot_called.png create mode 100644 application/assembly/src/main/res-call/raw/call_guide_single_data.json create mode 100644 application/assembly/src/main/res-call/raw/call_guide_with_app_data.json create mode 100644 application/assembly/src/main/res-call/raw/call_guide_with_web_data.json create mode 100644 application/assembly/src/main/res-call/values-en/strings.xml create mode 100644 application/assembly/src/main/res-call/values-zh/strings.xml create mode 100644 application/assembly/src/main/res-call/values/colors.xml create mode 100644 application/assembly/src/main/res-call/values/strings.xml create mode 100644 application/assembly/src/main/res-live/drawable-xxhdpi/live_list_ic_back.png create mode 100644 application/assembly/src/main/res-live/drawable-xxhdpi/live_list_ic_create_live.png create mode 100644 application/assembly/src/main/res-live/drawable-xxhdpi/live_list_ic_double_column.png create mode 100644 application/assembly/src/main/res-live/drawable-xxhdpi/live_list_ic_single_column.png create mode 100644 application/assembly/src/main/res-live/values-en/strings.xml create mode 100644 application/assembly/src/main/res-live/values-zh/strings.xml create mode 100644 application/assembly/src/main/res-live/values/strings.xml create mode 100644 application/assembly/src/main/res-room/values-en/strings.xml create mode 100644 application/assembly/src/main/res-room/values-zh/strings.xml create mode 100644 application/assembly/src/main/res-room/values/strings.xml create mode 100644 application/assembly/src/main/res-scenes-application/values-en/strings.xml create mode 100644 application/assembly/src/main/res-scenes-application/values-zh/strings.xml create mode 100644 application/assembly/src/main/res-scenes-application/values/strings.xml create mode 100644 application/assembly/src/main/res-voiceroom/drawable-xxhdpi/voice_room_ic_back.png create mode 100644 application/assembly/src/main/res-voiceroom/drawable-xxhdpi/voice_room_ic_create.png create mode 100644 application/assembly/src/main/res-voiceroom/values-en/strings.xml create mode 100644 application/assembly/src/main/res-voiceroom/values-zh/strings.xml create mode 100644 application/assembly/src/main/res-voiceroom/values/strings.xml create mode 100644 application/assembly/src/main/res/drawable/module_ic_beauty.png create mode 100644 application/assembly/src/main/res/drawable/module_ic_call.png create mode 100644 application/assembly/src/main/res/drawable/module_ic_chat.png create mode 100644 application/assembly/src/main/res/drawable/module_ic_live.png create mode 100644 application/assembly/src/main/res/drawable/module_ic_player.png rename application/{app/src/main/res/drawable/app_ic_main_meeting.png => assembly/src/main/res/drawable/module_ic_room.png} (100%) create mode 100644 application/assembly/src/main/res/drawable/module_ic_ugsv.png rename application/{app/src/main/res/drawable/app_ic_main_chatroom.png => assembly/src/main/res/drawable/module_ic_voiceroom.png} (100%) create mode 100644 application/assembly/src/main/res/values-en/strings.xml create mode 100644 application/assembly/src/main/res/values-zh/strings.xml create mode 100644 application/assembly/src/main/res/values/strings.xml delete mode 100644 application/debug/.gitignore delete mode 100644 application/debug/build.gradle delete mode 100644 application/debug/consumer-rules.pro delete mode 100644 application/debug/src/main/java/com/tencent/qcloud/tuikit/debug/GenerateTestUserSig.java delete mode 100644 application/gradlew.bat create mode 100644 application/login/build.gradle create mode 100644 application/login/consumer-rules.pro create mode 100644 application/login/src/main/AndroidManifest.xml create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/AgreementNavigator.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginActivity.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginConfig.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginEntry.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginMode.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginNavHost.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginSubStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginViewModel.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/LoginWebViewActivity.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/ServerEnvironment.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/model/AvatarModel.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/model/LoginError.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/model/LoginResult.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/model/UserModel.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/service/CaptchaService.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/service/LoginManager.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/service/LoginNetworkService.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/service/LoginService.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/service/TUILoginListenerHandler.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/views/AgreementView.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/views/CountdownButton.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/views/InviteCodeInputField.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/views/LoginComponents.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/views/LoginExtraComponents.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/components/views/PrivacyBottomDialog.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/debugauth/DebugAuthScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/debugauth/store/DebugAuthState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/debugauth/store/DebugAuthStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/devmenu/DevMenuScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/emailverify/EmailInviteCodeScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/emailverify/EmailVerifyScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/emailverify/store/EmailInviteCodeState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/emailverify/store/EmailInviteCodeStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/emailverify/store/EmailVerifyState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/emailverify/store/EmailVerifyStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/hiddenconfig/HiddenConfigCredentials.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/hiddenconfig/HiddenConfigScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/hiddenconfig/QRCodeScanScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/hiddenconfig/store/HiddenConfigState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/hiddenconfig/store/HiddenConfigStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/invitecode/InviteCodeScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/invitecode/store/InviteCodeState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/invitecode/store/InviteCodeStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/invitecode/utils/InviteCodeValidator.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/ioaauth/IOAAuthScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/ioaauth/store/IOAAuthState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/ioaauth/store/IOAAuthStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/phoneverify/PhoneVerifyScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/phoneverify/store/PhoneVerifyState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/phoneverify/store/PhoneVerifyStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/profile/AvatarSelectDialog.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/profile/ProfileScreen.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/profile/store/AvatarConstants.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/profile/store/ProfileState.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/profile/store/ProfileStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/tokenauth/store/TokenAuthStore.kt create mode 100644 application/login/src/main/kotlin/com/tencent/rtcube/v2/login/tokenauth/utils/TokenCacheManager.kt create mode 100644 application/login/src/main/res/drawable-xhdpi/login_bg_login_top.png create mode 100644 application/login/src/main/res/drawable-xhdpi/login_ic_cb_normal.png create mode 100644 application/login/src/main/res/drawable-xhdpi/login_ic_cb_select.png create mode 100755 application/login/src/main/res/drawable-xhdpi/login_ic_head.png create mode 100644 application/login/src/main/res/drawable-xhdpi/login_ic_phone.png create mode 100644 application/login/src/main/res/drawable-xhdpi/login_ic_safe.png create mode 100644 application/login/src/main/res/drawable-xhdpi/login_title_app.png rename application/{app/src/main/res/drawable/app_title_bar_back.png => login/src/main/res/drawable-xxhdpi/login_email_invite_back.png} (100%) create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_email_welcome_bg.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_email_welcome_logo.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_cb_normal.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_cb_select.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_full_screen_background.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_ioa.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_menu_debug.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_menu_email.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_menu_invite.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_menu_ioa.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_menu_phone.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_phone.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_qrcode.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_safe.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_sdkappid.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_user_id.png create mode 100644 application/login/src/main/res/drawable-xxhdpi/login_ic_user_sig.png rename application/{app/src/main/res/drawable/app_title_bar_back_light.png => login/src/main/res/drawable-xxhdpi/login_title_bar_back.png} (100%) create mode 100644 application/login/src/main/res/drawable/login_bg_terms_tooltip_arrow.xml create mode 100644 application/login/src/main/res/drawable/login_ic_arrow_right.xml create mode 100644 application/login/src/main/res/values-en/strings.xml create mode 100644 application/login/src/main/res/values-zh/strings.xml create mode 100644 application/login/src/main/res/values/colors.xml create mode 100644 application/login/src/main/res/values/strings.xml diff --git a/application/.gitignore b/application/.gitignore index 5c915a53..9a60edc2 100644 --- a/application/.gitignore +++ b/application/.gitignore @@ -14,3 +14,6 @@ .cxx local.properties .idea/ +app/build/ +login/build/ +assembly/build/ \ No newline at end of file diff --git a/application/README.cn.md b/application/README.cn.md new file mode 100644 index 00000000..b036b36e --- /dev/null +++ b/application/README.cn.md @@ -0,0 +1,95 @@ +# RTCube + +[English](README.md) | 简体中文 + +## 概述 + +RTCube 是一款功能强大的 UI 组件库,它基于腾讯云 `AtomicXCore` SDK 构建。`AtomicXCore` 整合了腾讯云实时音视频(TRTC)、即时通信(IM)、音视频通话(TUICallEngine) 和房间管理(TUIRoomEngine) 的核心能力,提供了状态驱动的(State-driven)API 设计。 + +RTCube 在 `AtomicXCore` 提供的核心能力之上,为您提供了一套预制的用户界面(UI),使您无需关心复杂的后端逻辑和状态管理,即可快速为您的 Android 应用集成视频互动直播、语音聊天室、音视频通话等功能。 + +## 功能特性 + +RTCube 基于 `AtomicXCore` 提供了以下核心业务场景的完整 UI 实现: + + * **视频/语音直播 (Live Streaming):** + + * **直播列表管理:** 拉取直播列表。 + * **开播与观看:** 创建直播间、加入直播。 + * **麦位管理:** 支持麦位管理,观众上麦/下麦。 + * **主播连麦 (Co-hosting):** 支持主播与主播(跨房)连麦。 + * **主播 PK (Battle):** 支持主播间 PK 互动。 + * **互动功能:** + * **礼物:** 支持发送和接收礼物。 + * **点赞:** 支持直播间点赞。 + * **弹幕:** 支持发送和接收弹幕消息。 + + * **音视频通话 (Calling):** + + * **基础通话:** 支持 1v1 及多人音视频通话。 + * **通话管理:** 支持接听、拒绝、挂断。 + * **设备管理:** 支持通话中的摄像头和麦克风控制。 + * **通话记录:** 支持查询和删除通话记录。 + + * **多人会议 (Room):** + + * **快速会议:** 支持一键创建/加入多人会议。 + * **邀请入会:** 支持邀请成员加入当前会议。 + * **会中管控:** 支持主持人对成员的音视频、麦位、成员列表进行管理。 + * **共享屏幕:** 支持会中屏幕共享。 + +## 快速开始 + +### 1. 环境准备 + + * Android Studio Giraffe (2022.3.1) 或更高版本 + * JDK 17 + * Android Gradle Plugin 8.x + * Android 7.0(API 24)或更高版本 + +### 2. 克隆仓库 + +```bash +git clone https://github.com/Tencent-RTC/TUIKit_Android.git +``` + +### 3. 打开工程 + +使用 Android Studio 打开 `TUIKit_Android/application` 目录,等待 Gradle 同步完成。 `settings.gradle` 中接入了 `tuilivekit`、`tuicallkit-kt`、`tuiroomkit` 等必要的 AtomicXCore 组件模块。 + +### 4. 运行项目 + +打开 `application/app/src/main/kotlin/com/tencent/rtcube/v2/debug/GenerateTestUserSig.kt`,填入您自己的腾讯云 `SDKAPPID` 与 `SECRETKEY`,然后编译并运行 `app` 模块。 + +## 架构 + +`RTCube` 的架构设计遵循分层原则: + +1. **TUILiveKit / TUICallKit / TUIRoomKit (UI 层):** + + * 提供预制的、可复用的 UI 组件。 + * 负责视图(View)的展示和用户交互。 + * 订阅 `AtomicXCore` 中的 `Store` 来获取状态并更新 UI。 + * 调用 `AtomicXCore` 中的 `Store` 方法来响应用户操作。 + +2. **AtomicXCore (核心层):** + + * **Stores:** (如 `LiveListStore`, `CallListStore`, `ConversationListStore`) 负责管理业务逻辑和状态(State)。 + * **Core Views:** (如 `LiveCoreView`, `ParticipantView`) 提供了驱动视频渲染的无 UI 视图容器。 + * **Engine 封装:** 封装了底层的 `RTCRoomEngine`, `TUICallEngine` 和 `IMSDK`,提供统一的 API。 + +3. **Tencent Cloud SDK (引擎层):** + + * `RTCRoomEngine` & `TUICallEngine`: 提供底层的实时音视频能力。 + * `IMSDK`: 提供即时通讯能力。 + +## 文档 + +* [AtomicXCore 文档](https://tencent-rtc.github.io/TUIKit_Android/documentation/atomicxcore) +* [官方文档 - 快速集成指南](https://cloud.tencent.com/document/product/647/106536) + +## 许可证 + +本项目遵循 [MIT 许可证](https://www.google.com/search?q=LICENSE)。 + +----- diff --git a/application/README.md b/application/README.md new file mode 100644 index 00000000..f98d2aa9 --- /dev/null +++ b/application/README.md @@ -0,0 +1,95 @@ +# RTCube + +English | [简体中文](README.cn.md) + +## Overview + +RTCube is a powerful UI component library built on top of the Tencent Cloud `AtomicXCore` SDK. `AtomicXCore` consolidates the core capabilities of Tencent Cloud Real-Time Communication (TRTC), Instant Messaging (IM), Audio/Video Calling (TUICallEngine), and Room Management (TUIRoomEngine), offering a state-driven API design. + +On top of the core capabilities provided by `AtomicXCore`, RTCube delivers a set of ready-to-use user interfaces (UI), allowing you to quickly integrate interactive video live streaming, voice chat rooms, audio/video calling, and more into your Android application—without worrying about complex backend logic or state management. + +## Features + +Based on `AtomicXCore`, RTCube provides complete UI implementations for the following core business scenarios: + + * **Video/Voice Live Streaming:** + + * **Live List Management:** Fetch the list of live streams. + * **Go Live & Watch:** Create live rooms and join live streams. + * **Seat Management:** Manage seats; audience members can take or leave the mic. + * **Co-hosting:** Support cross-room co-hosting between hosts. + * **Host Battle (PK):** Support interactive PK between hosts. + * **Interactive Features:** + * **Gifts:** Send and receive gifts. + * **Likes:** Send likes in the live room. + * **Barrage (Danmaku):** Send and receive barrage messages. + + * **Audio/Video Calling:** + + * **Basic Calls:** Support 1v1 and multi-party audio/video calls. + * **Call Management:** Support answering, rejecting, and hanging up calls. + * **Device Management:** Control the camera and microphone during calls. + * **Call History:** Query and delete call records. + + * **Multi-party Meetings (Room):** + + * **Quick Meetings:** One-click creation and joining of multi-party meetings. + * **Invite to Meeting:** Invite members to join the current meeting. + * **In-meeting Controls:** Hosts can manage members' audio/video, seats, and member list. + * **Screen Sharing:** Support screen sharing during meetings. + +## Quick Start + +### 1. Prerequisites + + * Android Studio Giraffe (2022.3.1) or later + * JDK 17 + * Android Gradle Plugin 8.x + * Android 7.0 (API 24) or later + +### 2. Clone the Repository + +```bash +git clone https://github.com/Tencent-RTC/TUIKit_Android.git +``` + +### 3. Open the Project + +Open `TUIKit_Android/application` with Android Studio and let Gradle sync the dependencies. All required AtomicXCore component modules (`tuilivekit`, `tuicallkit-kt`, `tuiroomkit`, etc.) are wired in through the top-level `settings.gradle`. + +### 4. Configure & Run + +Open `application/app/src/main/kotlin/com/tencent/rtcube/v2/debug/GenerateTestUserSig.kt`, fill in your Tencent Cloud `SDKAPPID` and `SECRETKEY`, then run the `app` module. + +## Architecture + +The architecture of `RTCube` follows a layered design: + +1. **TUILiveKit / TUICallKit / TUIRoomKit (UI Layer):** + + * Provides prebuilt, reusable UI components. + * Handles view presentation and user interaction. + * Subscribes to `Store`s in `AtomicXCore` to retrieve state and update the UI. + * Calls `Store` methods in `AtomicXCore` to respond to user actions. + +2. **AtomicXCore (Core Layer):** + + * **Stores:** (e.g., `LiveListStore`, `CallListStore`, `ConversationListStore`) Manage business logic and state. + * **Core Views:** (e.g., `LiveCoreView`, `ParticipantView`) Provide UI-less view containers that drive video rendering. + * **Engine Wrappers:** Wrap the underlying `RTCRoomEngine`, `TUICallEngine`, and `IMSDK`, providing a unified API. + +3. **Tencent Cloud SDK (Engine Layer):** + + * `RTCRoomEngine` & `TUICallEngine`: Provide low-level real-time audio/video capabilities. + * `IMSDK`: Provides instant messaging capabilities. + +## Documentation + +* [AtomicXCore Documentation](https://tencent-rtc.github.io/TUIKit_Android/documentation/atomicxcore) +* [Official Documentation - Quick Integration Guide](https://cloud.tencent.com/document/product/647/106536) + +## License + +This project is licensed under the [MIT License](https://www.google.com/search?q=LICENSE). + +----- diff --git a/application/app/.gitignore b/application/app/.gitignore deleted file mode 100644 index 42afabfd..00000000 --- a/application/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/application/app/build.gradle b/application/app/build.gradle index 21e6a0ee..81787aa3 100644 --- a/application/app/build.gradle +++ b/application/app/build.gradle @@ -2,28 +2,90 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - namespace 'com.tencent.uikit.app' + namespace 'com.tencent.rtcube.v2' compileSdk 34 defaultConfig { - applicationId "com.trtc.uikit.livekit.example" - minSdkVersion 21 - targetSdkVersion 34 - versionCode 1 - versionName "1.0" + applicationId 'com.tencent.trtc' + minSdk 24 + targetSdk 34 + versionCode = ((project.findProperty('RTCUBE_VERSION_CODE') ?: '2') as String).toInteger() + versionName = (project.findProperty('RTCUBE_VERSION_NAME') ?: '2.0.0').toString() + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + + ndk { + abiFilters 'arm64-v8a', 'armeabi-v7a' + } + + manifestPlaceholders = [ + // ioa party name, used for IOA integration; values injected from gradle.properties + ACCESS_PARTY_NAME: 'com_tencent_trtc', + // vivo / honor push identifier, used for TIMPush integration; values injected from gradle.properties + VIVO_APPKEY : (project.findProperty('RTCUBE_VIVO_APPKEY') ?: ''), + VIVO_APPID : (project.findProperty('RTCUBE_VIVO_APPID') ?: ''), + HONOR_APPID : (project.findProperty('RTCUBE_HONOR_APPID') ?: '') + ] + } + + signingConfigs { + release { + storeFile file("trtc.keystore") + storePassword "tencent.com" + keyAlias "tencent" + keyPassword "tencent.com" + } } buildTypes { release { + signingConfig signingConfigs.release minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - packagingOptions { - exclude '/META-INF/{AL2.0,LGPL2.1}' - exclude 'META-INF/LICENSE.txt' - exclude 'META-INF/NOTICE.txt' + flavorDimensions "channel" + productFlavors { + xiaomi { + dimension "channel" + applicationId "com.tencent.trtc" + } + rtcube { + dimension "channel" + applicationId "com.tencent.trtc" + } + tencentrtc { + dimension "channel" + applicationId "com.tencent.rtc.app" + } + rtcubelab { + dimension "channel" + applicationId "com.tencent.trtc" + isDefault true + } + } + + sourceSets { + main { + res.srcDirs( + 'src/main/res', + 'src/main/res-main', + 'src/main/res-mine', + 'src/main/res-privacy', + 'src/main/res-overseas' + ) + } + } + + buildFeatures { + viewBinding true + dataBinding true + buildConfig true + compose true + } + + composeOptions { + kotlinCompilerExtensionVersion '1.5.8' } compileOptions { @@ -32,24 +94,57 @@ android { } kotlinOptions { - jvmTarget = JavaVersion.VERSION_17 + jvmTarget = '17' + } + + lint { + error 'RtlHardcoded' + error 'RtlCompat' + error 'RtlEnabled' } } dependencies { - api project(':tuicallkit-kt') - api project(':tuilivekit') - api project(':tuiroomkit') - api rootProject.getProperties().containsKey("common") ? rootProject.ext.common : "io.trtc.uikit:common:3.3.0.1194" - api project(':debug') - - implementation("androidx.core:core:1.13.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation "androidx.navigation:navigation-fragment:2.1.0" - implementation 'androidx.appcompat:appcompat:1.3.1' - implementation 'androidx.cardview:cardview:1.0.0' - debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.14' - - androidTestImplementation libs.androidx.junit - androidTestImplementation libs.androidx.espresso.core -} \ No newline at end of file + implementation project(':login') + implementation project(':assembly') + + implementation libs.androidx.core.ktx + implementation libs.androidx.appcompat + implementation libs.androidx.activity.ktx + implementation libs.androidx.fragment.ktx + implementation libs.androidx.constraintlayout + implementation libs.material + + implementation libs.lifecycle.runtime.ktx + + implementation libs.kotlinx.coroutines.android + + implementation libs.okhttp + implementation libs.okhttp.logging + implementation libs.retrofit + implementation libs.retrofit.serialization + implementation libs.retrofit.gson + + implementation libs.kotlinx.serialization.json + + implementation libs.coil + implementation libs.coil.compose + + implementation platform(libs.compose.bom) + implementation libs.compose.ui + implementation libs.compose.ui.tooling.preview + implementation libs.compose.material3 + implementation libs.compose.foundation + implementation libs.compose.runtime + implementation libs.activity.compose + implementation libs.lifecycle.viewmodel.compose + implementation libs.lifecycle.runtime.compose + implementation libs.navigation.compose + debugImplementation libs.compose.ui.tooling + implementation 'com.journeyapps:zxing-android-embedded:4.3.0' + + debugImplementation libs.leakcanary + + // TIMPush + implementation 'com.tencent.timpush:timpush:latest.release' +} diff --git a/application/app/proguard-rules.pro b/application/app/proguard-rules.pro index 481bb434..9240dc7e 100644 --- a/application/app/proguard-rules.pro +++ b/application/app/proguard-rules.pro @@ -18,4 +18,39 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile +-keep class com.tencent.** { *; } + +-dontwarn com.tencent.bugly.** +-keep public class com.tencent.bugly.**{*;} + +-keep public class * extends com.qq.taf.jce.JceStruct{*;} + +-keep public class com.qq.jce.*{ +public * ; +protected * ; +} + +-keepclasseswithmembernames class * { + native ; +} + +-keep public interface com.tencent.feedback.eup.jni.NativeExceptionHandler{ +*; +} +-keep public class com.tencent.feedback.eup.jni.NativeExceptionUpload{ +*; +} +-keep public class com.tencent.bugly.crashreport.crash.jni.NativeExceptionHandler { + *; +} + +-keep class com.tencent.could.huiyansdk.** {*;} +-keep class com.tencent.could.aicamare.** {*;} +-keep class com.tencent.could.component.** {*;} +-keep class com.tencent.youtu.** {*;} +-keep class com.tencent.turingcam.** {*;} +-keep class com.tencent.turingfd.** {*;} +-keep class com.tenpay.utils.**{*;} +-keep class com.tencent.turingface.** {*;} +-keep class trpc.engine.yishan_websocket.** {*;} \ No newline at end of file diff --git a/application/app/src/androidTest/java/com/tencent/uikit/app/ExampleInstrumentedTest.kt b/application/app/src/androidTest/java/com/tencent/uikit/app/ExampleInstrumentedTest.kt deleted file mode 100644 index f3fadbf2..00000000 --- a/application/app/src/androidTest/java/com/tencent/uikit/app/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tencent.uikit.app - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.tencent.uikit.app", appContext.packageName) - } -} \ No newline at end of file diff --git a/application/app/src/main/AndroidManifest.xml b/application/app/src/main/AndroidManifest.xml index 140ae62f..d7de1774 100644 --- a/application/app/src/main/AndroidManifest.xml +++ b/application/app/src/main/AndroidManifest.xml @@ -2,25 +2,40 @@ + + + + + + + + + + - + tools:replace="android:allowBackup,android:theme,android:label" + android:theme="@style/Theme.RTCubeV2"> + + + + + android:theme="@style/Theme.RTCubeV2"> @@ -28,59 +43,15 @@ - - - - - - + android:theme="@style/Theme.RTCubeV2" /> + android:theme="@style/Theme.RTCubeV2" /> - - - - - - - - - - - - \ No newline at end of file + diff --git a/application/app/src/main/assets/timpush-configs.json b/application/app/src/main/assets/timpush-configs.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/application/app/src/main/assets/timpush-configs.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/utils/GlideEngine.kt b/application/app/src/main/java/com/tencent/uikit/app/common/utils/GlideEngine.kt deleted file mode 100644 index 93c2f523..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/utils/GlideEngine.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.tencent.uikit.app.common.utils - -import android.graphics.Bitmap -import android.widget.ImageView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.engine.DiskCacheStrategy -import com.bumptech.glide.request.RequestOptions -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.qcloud.tuicore.TUIThemeManager -import com.tencent.uikit.app.R -import java.util.concurrent.ExecutionException - -object GlideEngine { - - fun clear(imageView: ImageView) { - Glide.with(TUILogin.getAppContext()).clear(imageView) - } - - fun loadUserIcon(imageView: ImageView, uri: Any?) { - loadUserIcon(imageView, uri, 0) - } - - fun loadUserIcon(imageView: ImageView, uri: Any?, radius: Int) { - Glide.with(TUILogin.getAppContext()) - .load(uri) - .diskCacheStrategy(DiskCacheStrategy.ALL) - .placeholder(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.drawable.app_default_user_icon_light)) - .apply(RequestOptions().centerCrop().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.drawable.app_default_user_icon_light))) - .into(imageView) - } - - @Throws(InterruptedException::class, ExecutionException::class) - fun loadBitmap(imageUrl: Any?, targetImageSize: Int): Bitmap { - if (imageUrl == null) { - throw IllegalArgumentException("Image URL cannot be null") - } - return Glide.with(TUILogin.getAppContext()) - .asBitmap() - .load(imageUrl) - .apply(RequestOptions().error(TUIThemeManager.getAttrResId(TUILogin.getAppContext(), R.drawable.app_default_user_icon_light))) - .into(targetImageSize, targetImageSize) - .get() - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/utils/ImageUtil.kt b/application/app/src/main/java/com/tencent/uikit/app/common/utils/ImageUtil.kt deleted file mode 100644 index 92ecad90..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/utils/ImageUtil.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.tencent.uikit.app.common.utils - -import android.graphics.Bitmap -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.qcloud.tuicore.util.SPUtils -import java.io.File -import java.io.FileOutputStream -import java.io.IOException - -object ImageUtil { - const val SP_IMAGE = "_conversation_group_face" - - /** - * @param outFile - * @param bitmap - * @return - */ - fun storeBitmap(outFile: File, bitmap: Bitmap): File { - if (!outFile.exists() || outFile.isDirectory) { - outFile.parentFile?.mkdirs() - } - var fOut: FileOutputStream? = null - try { - outFile.deleteOnExit() - outFile.createNewFile() - fOut = FileOutputStream(outFile) - bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut) - fOut.flush() - } catch (e1: IOException) { - outFile.deleteOnExit() - } finally { - if (fOut != null) { - try { - fOut.close() - } catch (e: IOException) { - e.printStackTrace() - outFile.deleteOnExit() - } - } - } - return outFile - } - - fun setGroupConversationAvatar(conversationId: String, url: String) { - val spUtils = SPUtils.getInstance("${TUILogin.getSdkAppId()} $SP_IMAGE") - spUtils.put(conversationId, url) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/utils/LayoutUtil.kt b/application/app/src/main/java/com/tencent/uikit/app/common/utils/LayoutUtil.kt deleted file mode 100644 index bdbb73b4..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/utils/LayoutUtil.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.tencent.uikit.app.common.utils - -import android.content.Context -import android.content.res.Configuration -import android.view.View -import com.tencent.qcloud.tuicore.ServiceInitializer - -object LayoutUtil { - fun isRTL(): Boolean { - val context: Context = ServiceInitializer.getAppContext() - val configuration: Configuration = context.resources.configuration - val layoutDirection = configuration.layoutDirection - return layoutDirection == View.LAYOUT_DIRECTION_RTL - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/utils/SoftKeyBoardUtil.kt b/application/app/src/main/java/com/tencent/uikit/app/common/utils/SoftKeyBoardUtil.kt deleted file mode 100644 index ad3c10f2..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/utils/SoftKeyBoardUtil.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.tencent.uikit.app.common.utils - -import android.content.Context -import android.graphics.Rect -import android.os.IBinder -import android.util.DisplayMetrics -import android.view.View -import android.view.Window -import android.view.WindowManager -import android.view.inputmethod.InputMethodManager -import com.tencent.qcloud.tuicore.TUIConfig - -object SoftKeyBoardUtil { - fun hideKeyBoard(token: IBinder) { - val imm = TUIConfig.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? - imm?.hideSoftInputFromWindow(token, 0) - } - - fun hideKeyBoard(window: Window) { - val imm = TUIConfig.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? - if (imm != null) { - if (isSoftInputShown(window)) { - imm.toggleSoftInput(0, 0) - } - } - } - - fun showKeyBoard(window: Window) { - val imm = TUIConfig.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? - if (imm != null) { - if (!isSoftInputShown(window)) { - imm.toggleSoftInput(0, 0) - } - } - } - - private fun isSoftInputShown(window: Window): Boolean { - val decorView = window.decorView - val screenHeight = decorView.height - val rect = Rect() - decorView.getWindowVisibleDisplayFrame(rect) - return screenHeight - rect.bottom - getNavigateBarHeight(window.windowManager) >= 0 - } - - private fun getNavigateBarHeight(windowManager: WindowManager): Int { - val metrics = DisplayMetrics() - windowManager.defaultDisplay.getMetrics(metrics) - val usableHeight = metrics.heightPixels - windowManager.defaultDisplay.getRealMetrics(metrics) - val realHeight = metrics.heightPixels - return if (realHeight > usableHeight) { - realHeight - usableHeight - } else { - 0 - } - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/utils/ThreadUtils.kt b/application/app/src/main/java/com/tencent/uikit/app/common/utils/ThreadUtils.kt deleted file mode 100644 index f4bf94f5..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/utils/ThreadUtils.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.tencent.uikit.app.common.utils - -import android.os.Handler -import android.os.Looper -import java.util.concurrent.ExecutorService -import java.util.concurrent.Executors - -object ThreadUtils { - private val handler = Handler(Looper.getMainLooper()) - private val executors: ExecutorService = Executors.newCachedThreadPool() - - fun execute(runnable: Runnable) { - executors.execute(runnable) - } - - fun postOnUiThread(runnable: Runnable): Boolean { - return handler.post(runnable) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/BaseLightActivity.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/BaseLightActivity.kt deleted file mode 100644 index f1712095..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/BaseLightActivity.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.content.Context -import android.os.Build -import android.os.Bundle -import android.view.View -import android.view.WindowManager -import android.view.inputmethod.InputMethodManager -import androidx.appcompat.app.AppCompatActivity -import com.tencent.qcloud.tuicore.TUIThemeManager -import com.tencent.uikit.app.R - -open class BaseLightActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) - window.statusBarColor = resources.getColor( - TUIThemeManager.getAttrResId(this, com.tencent.qcloud.tuicore.R.attr.core_header_start_color) - ) - window.navigationBarColor = resources.getColor(R.color.app_color_navigation_bar) - var vis = window.decorView.systemUiVisibility - vis = vis or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR - vis = vis or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR - window.decorView.systemUiVisibility = vis - } - } - - override fun finish() { - hideSoftInput() - super.finish() - } - - fun hideSoftInput() { - val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - val window = window - if (window != null) { - imm.hideSoftInputFromWindow(window.decorView.windowToken, 0) - } - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/ConfirmDialogFragment.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/ConfirmDialogFragment.kt deleted file mode 100644 index b949ccda..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/ConfirmDialogFragment.kt +++ /dev/null @@ -1,93 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.app.Dialog -import android.os.Bundle -import android.text.TextUtils -import android.view.View -import android.widget.Button -import android.widget.TextView -import androidx.fragment.app.DialogFragment -import com.tencent.uikit.app.R - -class ConfirmDialogFragment : DialogFragment() { - private var positiveClickListener: PositiveClickListener? = - null - private var negativeClickListener: NegativeClickListener? = - null - - private var messageText: String? = null - private var positiveText: String? = null - private var negativeText: String? = null - private var buttonNegative: Button? = null - private var buttonPositive: Button? = null - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val dialog = Dialog(requireContext(), R.style.TRTCLiveConfirmDialogFragment) - dialog.setContentView(R.layout.app_dialog_confirm) - buttonPositive = dialog.findViewById(R.id.btn_positive) as Button - buttonNegative = dialog.findViewById(R.id.btn_negative) as Button - dialog.setCancelable(false) - initTextMessage(dialog) - initButtonPositive() - initButtonNegative() - return dialog - } - - private fun initTextMessage(dialog: Dialog) { - val textMessage = dialog.findViewById(R.id.tv_message) as TextView - textMessage.setText(messageText) - } - - private fun initButtonPositive() { - if (positiveClickListener == null) { - buttonPositive?.visibility = View.GONE - return - } - if (!TextUtils.isEmpty(positiveText)) { - buttonPositive?.text = positiveText - } - buttonPositive?.visibility = View.VISIBLE - buttonPositive?.setOnClickListener { positiveClickListener?.onClick() } - } - - private fun initButtonNegative() { - if (negativeClickListener == null) { - buttonNegative?.visibility = View.GONE - return - } - if (!TextUtils.isEmpty(negativeText)) { - buttonNegative?.text = negativeText - } - buttonNegative?.visibility = View.VISIBLE - buttonNegative?.setOnClickListener { negativeClickListener?.onClick() } - } - - fun setMessage(message: String?) { - messageText = message - } - - fun setPositiveText(text: String?) { - positiveText = text - buttonPositive?.visibility = View.VISIBLE - } - - fun setNegativeText(text: String?) { - negativeText = text - } - - fun setPositiveClickListener(listener: PositiveClickListener?) { - this.positiveClickListener = listener - } - - fun setNegativeClickListener(listener: NegativeClickListener?) { - this.negativeClickListener = listener - } - - interface PositiveClickListener { - fun onClick() - } - - interface NegativeClickListener { - fun onClick() - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/ITitleBarLayout.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/ITitleBarLayout.kt deleted file mode 100644 index b7d7c31a..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/ITitleBarLayout.kt +++ /dev/null @@ -1,116 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.view.View -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.TextView - -/** - * Conversation list window {@link ConversationLayout}、chat window {@link ChatLayout} have title bar, - * The title bar is designed as a three-part title on the left, middle and right. The left can be - * picture + text, the middle is text, and the right can also be picture + text. These areas return the - * standard Android View,These Views can be interactively processed according to business needs。 - */ -interface ITitleBarLayout { - /** - * Set the click event of the left header - * - * @param listener - */ - fun setOnLeftClickListener(listener: View.OnClickListener?) - - /** - * Set the click event of the right title - * - * @param listener - */ - fun setOnRightClickListener(listener: View.OnClickListener?) - - /** - * set Title - */ - fun setTitle(title: String?, position: Position?) - - /** - * Return to the left header area - * - * @return - */ - fun getLeftGroup(): LinearLayout - - /** - * Return to the right header area - * - * @return - */ - fun getRightGroup(): LinearLayout - - /** - * Returns the image for the left header - * - * @return - */ - fun getLeftIcon(): ImageView - - /** - * Set the image for the left header - * - * @param resId - */ - fun setLeftIcon(resId: Int) - - /** - * Returns the image with the right header - * - * @return - */ - fun getRightIcon(): ImageView - - /** - * Set the image for the title on the right - * - * @param resId - */ - fun setRightIcon(resId: Int) - - /** - * Returns the text of the left header - * - * @return - */ - fun getLeftTitle(): TextView - - /** - * Returns the text of the middle title - * - * @return - */ - fun getMiddleTitle(): TextView - - /** - * Returns the text of the title on the right - * - * @return - */ - fun getRightTitle(): TextView - - /** - * enumeration value of the header area - */ - enum class Position { - /** - * left title - */ - LEFT, - - /** - * middle title - */ - MIDDLE, - - /** - * right title - */ - RIGHT - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/ImageSelectActivity.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/ImageSelectActivity.kt deleted file mode 100644 index a80e5968..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/ImageSelectActivity.kt +++ /dev/null @@ -1,448 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.app.ProgressDialog -import android.content.Intent -import android.graphics.Rect -import android.os.Bundle -import android.text.TextUtils -import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Button -import android.widget.ImageView -import android.widget.RelativeLayout -import androidx.recyclerview.widget.GridLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.bumptech.glide.Glide -import com.bumptech.glide.load.DataSource -import com.bumptech.glide.load.engine.GlideException -import com.bumptech.glide.request.RequestListener -import com.bumptech.glide.request.RequestOptions -import com.bumptech.glide.request.target.Target -import com.tencent.qcloud.tuicore.TUIThemeManager -import com.tencent.uikit.app.R -import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast -import com.tencent.uikit.app.common.utils.LayoutUtil -import com.tencent.uikit.app.common.widget.gatherimage.SynthesizedImageView -import com.trtc.tuikit.common.util.ScreenUtil -import java.io.File -import java.io.Serializable - -class ImageSelectActivity : BaseLightActivity() { - companion object { - private val TAG = ImageSelectActivity::class.java.simpleName - - const val CHAT_CONVERSATION_BACKGROUND_DEFAULT_URL = - "chat/conversation/background/default/url" - const val RESULT_CODE_ERROR = -1 - const val RESULT_CODE_SUCCESS = 0 - const val TITLE = "title" - const val SPAN_COUNT = "spanCount" - const val DATA = "data" - const val ITEM_HEIGHT = "itemHeight" - const val ITEM_WIDTH = "itemWidth" - const val SELECTED = "selected" - const val PLACEHOLDER = "placeholder" - const val NEED_DOWNLOAD_LOCAL = "needDownload" - } - - private var defaultSpacing: Int = 0 - private var data: List? = null - private var selected: ImageBean? = null - private var placeHolder: Int = 0 - private var columnNum: Int = 0 - private lateinit var imageGrid: RecyclerView - private lateinit var gridLayoutManager: GridLayoutManager - private lateinit var gridAdapter: ImageGridAdapter - private lateinit var titleBarLayout: TitleBarLayout - private var itemHeight: Int = 0 - private var itemWidth: Int = 0 - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - defaultSpacing = ScreenUtil.dip2px(12f) - setContentView(R.layout.app_activity_image_select_layout) - - val intent = intent - val title = intent.getStringExtra(TITLE) - titleBarLayout = findViewById(R.id.image_select_title) - titleBarLayout.setTitle(title, ITitleBarLayout.Position.MIDDLE) - titleBarLayout.setTitle( - getString(com.tencent.qcloud.tuicore.R.string.sure), - ITitleBarLayout.Position.RIGHT - ) - titleBarLayout.getRightIcon().visibility = View.GONE - titleBarLayout.getRightTitle().setTextColor(0xFF006EFF.toInt()) - titleBarLayout.setOnLeftClickListener { - setResult(RESULT_CODE_ERROR) - finish() - } - - val needDownload = intent.getBooleanExtra(NEED_DOWNLOAD_LOCAL, false) - titleBarLayout.setOnRightClickListener { - if (selected == null) { - return@setOnRightClickListener - } - if (needDownload) { - downloadUrl() - } else { - val resultIntent = Intent() - resultIntent.putExtra(DATA, selected as Serializable) - setResult(RESULT_CODE_SUCCESS, resultIntent) - finish() - } - } - - @Suppress("UNCHECKED_CAST") - data = intent.getSerializableExtra(DATA) as? List - selected = intent.getSerializableExtra(SELECTED) as? ImageBean - placeHolder = intent.getIntExtra(PLACEHOLDER, 0) - itemHeight = intent.getIntExtra(ITEM_HEIGHT, 0) - itemWidth = intent.getIntExtra(ITEM_WIDTH, 0) - columnNum = intent.getIntExtra(SPAN_COUNT, 2) - gridLayoutManager = GridLayoutManager(this, columnNum) - imageGrid = findViewById(R.id.image_select_grid) - imageGrid.addItemDecoration(GridDecoration(columnNum, defaultSpacing, defaultSpacing)) - imageGrid.layoutManager = gridLayoutManager - imageGrid.itemAnimator = null - gridAdapter = ImageGridAdapter() - gridAdapter.setPlaceHolder(placeHolder) - gridAdapter.setSelected(selected) - gridAdapter.setOnItemClickListener { obj -> - selected = obj - setSelectedStatus() - } - gridAdapter.setItemWidth(itemWidth) - gridAdapter.setItemHeight(itemHeight) - imageGrid.adapter = gridAdapter - gridAdapter.setData(data) - setSelectedStatus() - gridAdapter.notifyDataSetChanged() - } - - private fun downloadUrl() { - if (selected == null) { - return - } - - if (selected!!.isDefault()) { - selected!!.setLocalPath(CHAT_CONVERSATION_BACKGROUND_DEFAULT_URL) - setResult(selected!!) - AtomicToast.show( - this, - resources.getString(R.string.app_set_success), - AtomicToast.Style.SUCCESS - ) - finish() - return - } - - val url = selected!!.getImageUri() - if (TextUtils.isEmpty(url)) { - Log.d(TAG, "DownloadUrl is null") - return - } - - val dialog = ProgressDialog(this) - dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER) - dialog.setCancelable(false) - dialog.setCanceledOnTouchOutside(false) - dialog.setOnDismissListener { - finish() - } - dialog.setMessage(resources.getString(R.string.app_setting)) - dialog.show() - - val finalBean = selected!! - Glide.with(this) - .downloadOnly() - .load(url) - .listener(object : RequestListener { - override fun onLoadFailed( - e: GlideException?, - model: Any?, - target: Target?, - isFirstResource: Boolean - ): Boolean { - dialog.cancel() - Log.e(TAG, "DownloadUrl onLoadFailed e = $e") - AtomicToast.show(this@ImageSelectActivity, resources.getString(R.string.app_set_fail), AtomicToast.Style.ERROR) - return false - } - - override fun onResourceReady( - resource: File?, - model: Any?, - target: Target?, - dataSource: DataSource?, - isFirstResource: Boolean - ): Boolean { - dialog.cancel() - val path = resource?.absolutePath - Log.e(TAG, "DownloadUrl resource path = $path") - finalBean.setLocalPath(path) - setResult(finalBean) - AtomicToast.show( - this@ImageSelectActivity, - resources.getString(R.string.app_set_success), - AtomicToast.Style.SUCCESS - ) - return false - } - }) - .preload() - } - - private fun setResult(bean: ImageBean) { - val resultIntent = Intent() - resultIntent.putExtra(DATA, bean as Serializable) - setResult(RESULT_CODE_SUCCESS, resultIntent) - finish() - } - - private fun setSelectedStatus() { - if (selected != null && data != null && data!!.contains(selected)) { - titleBarLayout.getRightTitle().isEnabled = true - titleBarLayout.getRightTitle().setTextColor( - resources.getColor( - TUIThemeManager.getAttrResId( - this, - com.tencent.qcloud.tuicore.R.attr.core_primary_color - ) - ) - ) - } else { - titleBarLayout.getRightTitle().isEnabled = false - titleBarLayout.getRightTitle().setTextColor(0xFF666666.toInt()) - } - gridAdapter.setSelected(selected) - } - - class ImageGridAdapter : RecyclerView.Adapter() { - private var itemWidth: Int = 0 - private var itemHeight: Int = 0 - private var data: List? = null - private var selected: ImageBean? = null - private var placeHolder: Int = 0 - private var onItemClickListener: OnItemClickListener? = null - - fun setData(data: List?) { - this.data = data - } - - fun setSelected(selected: ImageBean?) { - if (data == null || data!!.isEmpty()) { - this.selected = selected - } else { - this.selected = selected - notifyDataSetChanged() - } - } - - fun setPlaceHolder(placeHolder: Int) { - this.placeHolder = placeHolder - } - - fun setItemHeight(itemHeight: Int) { - this.itemHeight = itemHeight - } - - fun setItemWidth(itemWidth: Int) { - this.itemWidth = itemWidth - } - - fun setOnItemClickListener(onItemClickListener: OnItemClickListener) { - this.onItemClickListener = onItemClickListener - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder { - val view = - LayoutInflater.from(parent.context) - .inflate(R.layout.app_select_image_item_layout, parent, false) - return ImageViewHolder(view) - } - - override fun onBindViewHolder(holder: ImageViewHolder, position: Int) { - val imageView = holder.imageView - setItemLayoutParams(holder) - val imageBean = data!![position] - if (selected != null && imageBean != null && TextUtils.equals( - selected!!.getThumbnailUri(), - imageBean.getThumbnailUri() - ) - ) { - holder.selectBorderLayout.visibility = View.VISIBLE - } else { - holder.selectBorderLayout.visibility = View.GONE - } - - if (imageBean.getGroupGridAvatar() != null) { - holder.defaultLayout.visibility = View.GONE - if (imageView is SynthesizedImageView) { - val synthesizedImageView = imageView - val imageId = imageBean.getImageId() - synthesizedImageView.setImageId(imageId ?: "") - synthesizedImageView.displayImage(imageBean.getGroupGridAvatar()) - .load(imageId ?: "") - } - } else if (imageBean.isDefault()) { - holder.defaultLayout.visibility = View.VISIBLE - imageView.setImageResource(android.R.color.transparent) - } else { - holder.defaultLayout.visibility = View.GONE - Glide.with(holder.itemView.context) - .asBitmap() - .load(imageBean.getThumbnailUri()) - .placeholder(placeHolder) - .apply(RequestOptions().error(placeHolder)) - .into(imageView) - } - - holder.itemView.setOnClickListener { - onItemClickListener?.onClick(imageBean) - } - } - - private fun setItemLayoutParams(holder: ImageViewHolder) { - if (itemHeight > 0 && itemWidth > 0) { - val itemViewLayoutParams = holder.itemView.layoutParams - itemViewLayoutParams.width = itemWidth - itemViewLayoutParams.height = itemHeight - holder.itemView.layoutParams = itemViewLayoutParams - - val params = holder.imageView.layoutParams - params.width = itemWidth - params.height = itemHeight - holder.imageView.layoutParams = params - - val borderLayoutParams = holder.selectBorderLayout.layoutParams - borderLayoutParams.width = itemWidth - borderLayoutParams.height = itemHeight - holder.selectBorderLayout.layoutParams = borderLayoutParams - - val borderParams = holder.selectedBorder.layoutParams - borderParams.width = itemWidth - borderParams.height = itemHeight - holder.selectedBorder.layoutParams = borderParams - } - } - - override fun getItemCount(): Int { - return if (data == null || data!!.isEmpty()) { - 0 - } else data!!.size - } - - class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - val imageView: ImageView = itemView.findViewById(R.id.content_image) - val selectedBorder: ImageView = itemView.findViewById(R.id.select_border) - val selectBorderLayout: RelativeLayout = - itemView.findViewById(R.id.selected_border_area) - val defaultLayout: Button = itemView.findViewById(R.id.default_image_layout) - } - } - - /** - * add spacing - */ - class GridDecoration( - private val columnNum: Int, // span count - private val leftRightSpace: Int, // vertical spacing - private val topBottomSpace: Int // horizontal spacing - ) : RecyclerView.ItemDecoration() { - - override fun getItemOffsets( - outRect: Rect, - view: View, - parent: RecyclerView, - state: RecyclerView.State - ) { - val position = parent.getChildAdapterPosition(view) - val column = position % columnNum - - val left = column * leftRightSpace / columnNum - val right = leftRightSpace * (columnNum - 1 - column) / columnNum - if (LayoutUtil.isRTL()) { - outRect.left = right - outRect.right = left - } else { - outRect.left = left - outRect.right = right - } - // add top spacing - if (position >= columnNum) { - outRect.top = topBottomSpace - } - } - } - - fun interface OnItemClickListener { - fun onClick(obj: ImageBean) - } - - class ImageBean : Serializable { - private var thumbnailUri: String? = null // for display - internal var imageUri: String? = null // for download - private var localPath: String? = null // for local path - private var isDefault = false // for default display - private var groupGridAvatar: List? = null // for group grid avatar - private var imageId: String? = null - - constructor() - - constructor(thumbnailUri: String?, imageUri: String?, isDefault: Boolean) { - this.thumbnailUri = thumbnailUri - this.imageUri = imageUri - this.isDefault = isDefault - } - - fun getImageUri(): String? { - return imageUri - } - - fun getThumbnailUri(): String? { - return thumbnailUri - } - - fun setImageUri(imageUri: String?) { - this.imageUri = imageUri - } - - fun setThumbnailUri(thumbnailUri: String?) { - this.thumbnailUri = thumbnailUri - } - - fun getLocalPath(): String? { - return localPath - } - - fun setLocalPath(localPath: String?) { - this.localPath = localPath - } - - fun isDefault(): Boolean { - return isDefault - } - - fun setDefault(aDefault: Boolean) { - isDefault = aDefault - } - - fun getGroupGridAvatar(): List? { - return groupGridAvatar - } - - fun setGroupGridAvatar(groupGridAvatar: List?) { - this.groupGridAvatar = groupGridAvatar - } - - fun getImageId(): String? { - return imageId - } - - fun setImageId(imageId: String?) { - this.imageId = imageId - } - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/PopupInputCard.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/PopupInputCard.kt deleted file mode 100644 index e3c92a58..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/PopupInputCard.kt +++ /dev/null @@ -1,248 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.animation.ValueAnimator -import android.app.Activity -import android.graphics.drawable.ColorDrawable -import android.text.Editable -import android.text.InputFilter -import android.text.Spanned -import android.text.TextUtils -import android.text.TextWatcher -import android.view.LayoutInflater -import android.view.View -import android.view.Window -import android.view.WindowManager -import android.view.animation.LinearInterpolator -import android.widget.Button -import android.widget.EditText -import android.widget.PopupWindow -import android.widget.TextView -import com.tencent.uikit.app.R -import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast -import com.tencent.uikit.app.common.utils.SoftKeyBoardUtil -import java.util.regex.Pattern - -class PopupInputCard(private val activity: Activity) { - private var popupWindow: PopupWindow - private lateinit var titleTv: TextView - private lateinit var editText: EditText - private lateinit var descriptionTv: TextView - private lateinit var positiveBtn: Button - private lateinit var closeBtn: View - private var positiveOnClickListener: OnClickListener? = null - private var textExceedListener: OnTextExceedListener? = null - - private var minLimit = 0 - private var maxLimit = Int.MAX_VALUE - private var rule: String? = null - private var notMachRuleTip: String? = null - private val lengthFilter = ByteLengthFilter() - - init { - val popupView = LayoutInflater.from(activity).inflate(R.layout.app_layout_popup_card, null) - titleTv = popupView.findViewById(R.id.popup_card_title) - editText = popupView.findViewById(R.id.popup_card_edit) - descriptionTv = popupView.findViewById(R.id.popup_card_description) - positiveBtn = popupView.findViewById(R.id.popup_card_positive_btn) - closeBtn = popupView.findViewById(R.id.close_btn) - - popupWindow = object : PopupWindow(popupView, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT, true) { - override fun showAtLocation(anchor: View?, gravity: Int, x: Int, y: Int) { - if (!activity.isFinishing) { - val dialogWindow = activity.window - startAnimation(dialogWindow, true) - } - editText.requestFocus() - if (activity.window != null) { - SoftKeyBoardUtil.showKeyBoard(activity.window) - } - super.showAtLocation(anchor, gravity, x, y) - } - - override fun dismiss() { - if (!activity.isFinishing) { - val dialogWindow = activity.window - startAnimation(dialogWindow, false) - } - super.dismiss() - } - } - - popupWindow.setBackgroundDrawable(ColorDrawable()) - popupWindow.isTouchable = true - popupWindow.isOutsideTouchable = false - popupWindow.animationStyle = R.style.PopupInputCardAnim - popupWindow.inputMethodMode = PopupWindow.INPUT_METHOD_NEEDED - popupWindow.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE - popupWindow.setOnDismissListener { - if (activity.window != null) { - SoftKeyBoardUtil.hideKeyBoard(activity.window) - } - } - - positiveBtn.setOnClickListener { - val result = editText.text.toString() - - if (result.length < minLimit || result.length > maxLimit) { - AtomicToast.show(activity, notMachRuleTip ?: "", AtomicToast.Style.ERROR) - return@setOnClickListener - } - - if (!TextUtils.isEmpty(rule) && !Pattern.matches(rule, result)) { - AtomicToast.show(activity, notMachRuleTip ?: "", AtomicToast.Style.ERROR) - return@setOnClickListener - } - - positiveOnClickListener?.onClick(editText.text.toString()) - popupWindow.dismiss() - } - - closeBtn.setOnClickListener { - popupWindow.dismiss() - } - - editText.filters = arrayOf(lengthFilter) - editText.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} - - override fun afterTextChanged(s: Editable?) { - if (!TextUtils.isEmpty(rule)) { - if (!Pattern.matches(rule, s.toString())) { - positiveBtn.isEnabled = false - } else { - positiveBtn.isEnabled = true - } - } - } - }) - } - - private fun startAnimation(window: Window, isShow: Boolean) { - val animator: ValueAnimator = if (isShow) { - ValueAnimator.ofFloat(1.0f, 0.5f) - } else { - ValueAnimator.ofFloat(0.5f, 1.0f) - } - animator.addUpdateListener { animation -> - val lp = window.attributes - lp.alpha = animation.animatedValue as Float - window.attributes = lp - } - val interpolator = LinearInterpolator() - animator.duration = 200 - animator.interpolator = interpolator - animator.start() - } - - fun show(rootView: View?, gravity: Int) { - popupWindow.showAtLocation(rootView, gravity, 0, 0) - } - - fun setTitle(title: String?) { - titleTv.text = title - } - - fun setDescription(description: String?) { - if (!TextUtils.isEmpty(description)) { - descriptionTv.visibility = View.VISIBLE - descriptionTv.text = description - } - } - - fun setContent(content: String?) { - editText.setText(content) - } - - fun setOnPositive(clickListener: OnClickListener?) { - positiveOnClickListener = clickListener - } - - fun setTextExceedListener(textExceedListener: OnTextExceedListener?) { - this.textExceedListener = textExceedListener - } - - fun setSingleLine(isSingleLine: Boolean) { - editText.isSingleLine = isSingleLine - } - - fun setMaxLimit(maxLimit: Int) { - this.maxLimit = maxLimit - lengthFilter.setLength(maxLimit) - } - - fun setMinLimit(minLimit: Int) { - this.minLimit = minLimit - } - - fun setRule(rule: String?) { - this.rule = if (TextUtils.isEmpty(rule)) { - "" - } else { - rule - } - } - - fun setNotMachRuleTip(notMachRuleTip: String?) { - this.notMachRuleTip = notMachRuleTip - } - - inner class ByteLengthFilter : InputFilter { - private var length = Int.MAX_VALUE - - fun setLength(length: Int) { - this.length = length - } - - override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence? { - var destLength = 0 - var destReplaceLength = 0 - var sourceLength = 0 - if (!TextUtils.isEmpty(dest)) { - destLength = dest.toString().toByteArray().size - destReplaceLength = dest!!.subSequence(dstart, dend).toString().toByteArray().size - } - if (!TextUtils.isEmpty(source)) { - sourceLength = source!!.subSequence(start, end).toString().toByteArray().size - } - val keepBytesLength = length - (destLength - destReplaceLength) - return if (keepBytesLength <= 0) { - textExceedListener?.onTextExceedMax() - "" - } else if (keepBytesLength >= sourceLength) { - null - } else { - textExceedListener?.onTextExceedMax() - getSource(source!!, start, keepBytesLength) - } - } - - private fun getSource(sequence: CharSequence, start: Int, keepLength: Int): CharSequence { - val sequenceLength = sequence.length - var end = 0 - for (i in 1..sequenceLength) { - if (sequence.subSequence(0, i).toString().toByteArray().size <= keepLength) { - end = i - } else { - break - } - } - if (end > 0 && Character.isHighSurrogate(sequence[end - 1])) { - --end - if (end == start) { - return "" - } - } - return sequence.subSequence(start, end) - } - } - - fun interface OnClickListener { - fun onClick(result: String) - } - - interface OnTextExceedListener { - fun onTextExceedMax() - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/RecycleFragmentNavigator.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/RecycleFragmentNavigator.kt deleted file mode 100644 index 83b131a1..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/RecycleFragmentNavigator.kt +++ /dev/null @@ -1,139 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.content.Context -import android.os.Bundle -import android.util.Log -import androidx.annotation.IdRes -import androidx.fragment.app.FragmentManager -import androidx.navigation.NavDestination -import androidx.navigation.NavOptions -import androidx.navigation.Navigator -import androidx.navigation.fragment.FragmentNavigator -import java.util.ArrayDeque - -/** - * Navigation 默认加载 fragment 的模式,每次会重新加载 view,导致每次导航切换的时候会重新加载view, - * 通过重写 FragmentNavigator 的 navigate 方法,将其中的 replace 方法 替换为 show 和 hide 方法 来完成 Fragment 的切换, - * 在应用切换导航的时候,会回收之前的view,避免每次重复加载fragment - */ -@Navigator.Name("RecycleFragmentNavigator") -class RecycleFragmentNavigator( - private val mContext: Context, - private val mManager: FragmentManager, - private val mContainerId: Int -) : FragmentNavigator( - mContext, - mManager, - mContainerId -) { - override fun navigate( - destination: FragmentNavigator.Destination, - args: Bundle?, - navOptions: NavOptions?, - navigatorExtras: Navigator.Extras? - ): NavDestination? { - if (mManager.isStateSaved) { - Log.i(TAG, "Ignoring navigate() call: FragmentManager has already" + " saved its state") - return null - } - var className = destination.getClassName() - if (className.get(0) == '.') { - className = mContext.getPackageName() + className - } - val ft = mManager.beginTransaction() - var enterAnim = navOptions?.enterAnim ?: -1 - var exitAnim = navOptions?.exitAnim ?: -1 - var popEnterAnim = navOptions?.popEnterAnim ?: -1 - var popExitAnim = navOptions?.popExitAnim ?: -1 - if (enterAnim != -1 || exitAnim != -1 || popEnterAnim != -1 || popExitAnim != -1) { - enterAnim = if (enterAnim != -1) enterAnim else 0 - exitAnim = if (exitAnim != -1) exitAnim else 0 - popEnterAnim = if (popEnterAnim != -1) popEnterAnim else 0 - popExitAnim = if (popExitAnim != -1) popExitAnim else 0 - ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim) - } - - /** - * 1、先查询当前显示的fragment 不为空则将其hide - * 2、根据tag查询当前添加的fragment是否不为null,不为null则将其直接show - * 3、为null则通过instantiateFragment方法创建fragment实例 - * 4、将创建的实例添加在事务中 - */ - val fragment = mManager.primaryNavigationFragment //当前显示的fragment - if (fragment != null) { - ft.hide(fragment) - } - - val tag = destination.getId().toString() - var frag = mManager.findFragmentByTag(tag) - if (frag != null) { - ft.show(frag) - } else { - frag = instantiateFragment(mContext, mManager, className, args) - frag.setArguments(args) - ft.add(mContainerId, frag, tag) - } - ft.setPrimaryNavigationFragment(frag) - - @IdRes val destId = destination.getId() - - var mBackStack: ArrayDeque? = null - var isAdded = false - try { - val navigationClass = Class.forName("androidx.navigation.fragment.FragmentNavigator") - val field = navigationClass.getDeclaredField("mBackStack") - field.setAccessible(true) - mBackStack = field.get(this) as ArrayDeque? - val initialNavigation = mBackStack!!.isEmpty() - val isSingleTopReplacement = - (navOptions != null && !initialNavigation && navOptions.shouldLaunchSingleTop() - && mBackStack.peekLast() == destId) - - if (initialNavigation) { - isAdded = true - } else if (isSingleTopReplacement) { - if (mBackStack.size > 1) { - mManager.popBackStack( - generateBackStackName(mBackStack.size, mBackStack.peekLast()!!), - FragmentManager.POP_BACK_STACK_INCLUSIVE - ) - ft.addToBackStack(generateBackStackName(mBackStack.size, destId)) - } - } else { - ft.addToBackStack(generateBackStackName(mBackStack.size + 1, destId)) - } - if (navigatorExtras is Extras) { - val extras = navigatorExtras - for (sharedElement in extras.getSharedElements().entries) { - ft.addSharedElement(sharedElement.key, sharedElement.value) - } - } - ft.setReorderingAllowed(true) - ft.commit() - } catch (e: ClassNotFoundException) { - Log.e(TAG, "addToBackStack error, message is: " + e.message) - e.printStackTrace() - } catch (e: NoSuchFieldException) { - Log.e(TAG, "addToBackStack error, message is: " + e.message) - e.printStackTrace() - } catch (e: IllegalAccessException) { - Log.e(TAG, "addToBackStack error, message is: " + e.message) - e.printStackTrace() - } - - if (mBackStack != null && isAdded) { - mBackStack.add(destId) - return destination - } else { - return null - } - } - - private fun generateBackStackName(backIndex: Int, destId: Int): String { - return "$backIndex - $destId" - } - - companion object { - private const val TAG = "FixFragmentNavigator" - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundCornerImageView.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundCornerImageView.kt deleted file mode 100644 index 32b37ac5..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundCornerImageView.kt +++ /dev/null @@ -1,121 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.content.Context -import android.content.res.TypedArray -import android.graphics.Canvas -import android.graphics.Paint -import android.graphics.PaintFlagsDrawFilter -import android.graphics.Path -import android.graphics.RectF -import android.util.AttributeSet -import android.view.View -import androidx.appcompat.widget.AppCompatImageView -import com.tencent.uikit.app.R - -class RoundCornerImageView : AppCompatImageView { - private val path = Path() - private val rectF = RectF() - private val aliasFilter = PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG) - private var radius: Int = 0 - private var leftTopRadius: Int = 0 - private var rightTopRadius: Int = 0 - private var rightBottomRadius: Int = 0 - private var leftBottomRadius: Int = 0 - - constructor(context: Context) : super(context) { - init(context, null) - } - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { - init(context, attrs) - } - - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - - private fun init(context: Context, attrs: AttributeSet?) { - setLayerType(View.LAYER_TYPE_HARDWARE, null) - val defaultRadius = 0 - if (attrs != null) { - val array: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundCornerImageView) - radius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_corner_radius, defaultRadius) - leftTopRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_left_top_corner_radius, defaultRadius) - rightTopRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_right_top_corner_radius, defaultRadius) - rightBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_right_bottom_corner_radius, defaultRadius) - leftBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundCornerImageView_left_bottom_corner_radius, defaultRadius) - array.recycle() - } - - if (defaultRadius == leftTopRadius) { - leftTopRadius = radius - } - if (defaultRadius == rightTopRadius) { - rightTopRadius = radius - } - if (defaultRadius == rightBottomRadius) { - rightBottomRadius = radius - } - if (defaultRadius == leftBottomRadius) { - leftBottomRadius = radius - } - } - - fun setLeftBottomRadius(leftBottomRadius: Int) { - this.leftBottomRadius = leftBottomRadius - } - - fun setLeftTopRadius(leftTopRadius: Int) { - this.leftTopRadius = leftTopRadius - } - - fun setRadius(radius: Int) { - this.radius = radius - leftBottomRadius = radius - rightBottomRadius = radius - rightTopRadius = radius - leftTopRadius = radius - } - - fun setRightBottomRadius(rightBottomRadius: Int) { - this.rightBottomRadius = rightBottomRadius - } - - fun setRightTopRadius(rightTopRadius: Int) { - this.rightTopRadius = rightTopRadius - } - - fun getLeftBottomRadius(): Int { - return leftBottomRadius - } - - fun getLeftTopRadius(): Int { - return leftTopRadius - } - - fun getRadius(): Int { - return radius - } - - fun getRightBottomRadius(): Int { - return rightBottomRadius - } - - fun getRightTopRadius(): Int { - return rightTopRadius - } - - override fun onDraw(canvas: Canvas) { - path.reset() - canvas.drawFilter = aliasFilter - rectF.set(0f, 0f, measuredWidth.toFloat(), measuredHeight.toFloat()) - // left-top -> right-top -> right-bottom -> left-bottom - val radius = floatArrayOf( - leftTopRadius.toFloat(), leftTopRadius.toFloat(), - rightTopRadius.toFloat(), rightTopRadius.toFloat(), - rightBottomRadius.toFloat(), rightBottomRadius.toFloat(), - leftBottomRadius.toFloat(), leftBottomRadius.toFloat() - ) - path.addRoundRect(rectF, radius, Path.Direction.CW) - canvas.clipPath(path) - super.onDraw(canvas) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundFrameLayout.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundFrameLayout.kt deleted file mode 100644 index 3c4cafb1..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/RoundFrameLayout.kt +++ /dev/null @@ -1,121 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.content.Context -import android.content.res.TypedArray -import android.graphics.Canvas -import android.graphics.Paint -import android.graphics.PaintFlagsDrawFilter -import android.graphics.Path -import android.graphics.RectF -import android.util.AttributeSet -import android.view.View -import android.widget.FrameLayout -import com.tencent.uikit.app.R - -class RoundFrameLayout : FrameLayout { - private val path = Path() - private val rectF = RectF() - private val aliasFilter = PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG) - private var radius: Int = 0 - private var leftTopRadius: Int = 0 - private var rightTopRadius: Int = 0 - private var rightBottomRadius: Int = 0 - private var leftBottomRadius: Int = 0 - - constructor(context: Context) : super(context) { - init(context, null) - } - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { - init(context, attrs) - } - - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - - private fun init(context: Context, attrs: AttributeSet?) { - setLayerType(View.LAYER_TYPE_HARDWARE, null) - val defaultRadius = 0 - if (attrs != null) { - val array: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundFrameLayout) - radius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_corner_radius, defaultRadius) - leftTopRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_left_top_corner_radius, defaultRadius) - rightTopRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_right_top_corner_radius, defaultRadius) - rightBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_right_bottom_corner_radius, defaultRadius) - leftBottomRadius = array.getDimensionPixelOffset(R.styleable.RoundFrameLayout_left_bottom_corner_radius, defaultRadius) - array.recycle() - } - - if (defaultRadius == leftTopRadius) { - leftTopRadius = radius - } - if (defaultRadius == rightTopRadius) { - rightTopRadius = radius - } - if (defaultRadius == rightBottomRadius) { - rightBottomRadius = radius - } - if (defaultRadius == leftBottomRadius) { - leftBottomRadius = radius - } - } - - fun setLeftBottomRadius(leftBottomRadius: Int) { - this.leftBottomRadius = leftBottomRadius - } - - fun setLeftTopRadius(leftTopRadius: Int) { - this.leftTopRadius = leftTopRadius - } - - fun setRadius(radius: Int) { - this.radius = radius - leftBottomRadius = radius - rightBottomRadius = radius - rightTopRadius = radius - leftTopRadius = radius - } - - fun setRightBottomRadius(rightBottomRadius: Int) { - this.rightBottomRadius = rightBottomRadius - } - - fun setRightTopRadius(rightTopRadius: Int) { - this.rightTopRadius = rightTopRadius - } - - fun getLeftBottomRadius(): Int { - return leftBottomRadius - } - - fun getLeftTopRadius(): Int { - return leftTopRadius - } - - fun getRadius(): Int { - return radius - } - - fun getRightBottomRadius(): Int { - return rightBottomRadius - } - - fun getRightTopRadius(): Int { - return rightTopRadius - } - - override fun dispatchDraw(canvas: Canvas) { - path.reset() - canvas.drawFilter = aliasFilter - rectF.set(0f, 0f, measuredWidth.toFloat(), measuredHeight.toFloat()) - // left-top -> right-top -> right-bottom -> left-bottom - val radius = floatArrayOf( - leftTopRadius.toFloat(), leftTopRadius.toFloat(), - rightTopRadius.toFloat(), rightTopRadius.toFloat(), - rightBottomRadius.toFloat(), rightBottomRadius.toFloat(), - leftBottomRadius.toFloat(), leftBottomRadius.toFloat() - ) - path.addRoundRect(rectF, radius, Path.Direction.CW) - canvas.clipPath(path) - super.dispatchDraw(canvas) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/TitleBarLayout.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/TitleBarLayout.kt deleted file mode 100644 index 65cdc6b3..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/TitleBarLayout.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.app.Activity -import android.content.Context -import android.content.res.TypedArray -import android.graphics.drawable.Drawable -import android.text.TextUtils -import android.util.AttributeSet -import android.view.View -import android.view.ViewGroup -import android.view.inputmethod.InputMethodManager -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.RelativeLayout -import android.widget.TextView -import com.tencent.qcloud.tuicore.TUIThemeManager -import com.tencent.uikit.app.R -import com.trtc.tuikit.common.util.ScreenUtil - -class TitleBarLayout : LinearLayout, ITitleBarLayout { - private lateinit var mLeftGroup: LinearLayout - private lateinit var mRightGroup: LinearLayout - private lateinit var mLeftTitle: TextView - private lateinit var mCenterTitle: TextView - private lateinit var mRightTitle: TextView - private lateinit var mLeftIcon: ImageView - private lateinit var mRightIcon: ImageView - private lateinit var mTitleLayout: RelativeLayout - private lateinit var unreadCountTextView: UnreadCountTextView - - constructor(context: Context) : super(context) { - init(context, null) - } - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { - init(context, attrs) - } - - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { - init(context, attrs) - } - - private fun init(context: Context, attrs: AttributeSet?) { - var middleTitle: String? = null - var canReturn = false - if (attrs != null) { - val array: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleBarLayout) - middleTitle = array.getString(R.styleable.TitleBarLayout_title_bar_middle_title) - canReturn = array.getBoolean(R.styleable.TitleBarLayout_title_bar_can_return, false) - array.recycle() - } - inflate(context, R.layout.app_layout_title_bar, this) - mTitleLayout = findViewById(R.id.page_title_layout) - mLeftGroup = findViewById(R.id.page_title_left_group) - mRightGroup = findViewById(R.id.page_title_right_group) - mLeftTitle = findViewById(R.id.page_title_left_text) - mRightTitle = findViewById(R.id.page_title_right_text) - mCenterTitle = findViewById(R.id.page_title) - mLeftIcon = findViewById(R.id.page_title_left_icon) - val leftIconDrawable: Drawable? = mLeftIcon.background - leftIconDrawable?.isAutoMirrored = true - mRightIcon = findViewById(R.id.page_title_right_icon) - unreadCountTextView = findViewById(R.id.new_message_total_unread) - - val params = mTitleLayout.layoutParams as LayoutParams - params.height = ScreenUtil.getPxByDp(50f) - mTitleLayout.layoutParams = params - setBackgroundResource(TUIThemeManager.getAttrResId(context, R.drawable.app_title_bar_bg_light)) - - val iconSize = ScreenUtil.dip2px(20f) - var iconParams = mLeftIcon.layoutParams - iconParams.width = iconSize - iconParams.height = iconSize - mLeftIcon.layoutParams = iconParams - iconParams = mRightIcon.layoutParams - iconParams.width = iconSize - iconParams.height = iconSize - - mRightIcon.layoutParams = iconParams - - if (canReturn) { - setLeftReturnListener(context) - } - if (!TextUtils.isEmpty(middleTitle)) { - mCenterTitle.text = middleTitle - } - } - - fun setLeftReturnListener(context: Context) { - mLeftGroup.setOnClickListener { - if (context is Activity) { - val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(this@TitleBarLayout.windowToken, 0) - context.finish() - } - } - } - - override fun setOnLeftClickListener(listener: OnClickListener?) { - mLeftGroup.setOnClickListener(listener) - } - - override fun setOnRightClickListener(listener: OnClickListener?) { - mRightGroup.setOnClickListener(listener) - } - - override fun setTitle(title: String?, position: ITitleBarLayout.Position?) { - when (position) { - ITitleBarLayout.Position.LEFT -> mLeftTitle.text = title - ITitleBarLayout.Position.RIGHT -> mRightTitle.text = title - ITitleBarLayout.Position.MIDDLE -> mCenterTitle.text = title - else -> {} - } - } - - override fun getLeftGroup(): LinearLayout { - return mLeftGroup - } - - override fun getRightGroup(): LinearLayout { - return mRightGroup - } - - override fun getLeftIcon(): ImageView { - return mLeftIcon - } - - override fun setLeftIcon(resId: Int) { - mLeftIcon.setBackgroundResource(resId) - } - - override fun getRightIcon(): ImageView { - return mRightIcon - } - - override fun setRightIcon(resId: Int) { - mRightIcon.setBackgroundResource(resId) - } - - override fun getLeftTitle(): TextView { - return mLeftTitle - } - - override fun getMiddleTitle(): TextView { - return mCenterTitle - } - - override fun getRightTitle(): TextView { - return mRightTitle - } - - fun getUnreadCountTextView(): UnreadCountTextView { - return unreadCountTextView - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/UnreadCountTextView.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/UnreadCountTextView.kt deleted file mode 100644 index a4e573ad..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/UnreadCountTextView.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.tencent.uikit.app.common.widget - -import android.content.Context -import android.content.res.TypedArray -import android.graphics.Canvas -import android.graphics.Paint -import android.graphics.RectF -import android.util.AttributeSet -import android.util.DisplayMetrics -import android.util.TypedValue -import android.view.View -import androidx.appcompat.widget.AppCompatTextView -import com.tencent.uikit.app.R - -class UnreadCountTextView : AppCompatTextView { - private var mNormalSize: Int = 0 - private lateinit var mPaint: Paint - - constructor(context: Context) : super(context) { - init(context, null) - } - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { - init(context, attrs) - } - - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { - init(context, attrs) - } - - private fun init(context: Context, attrs: AttributeSet?) { - textDirection = View.TEXT_DIRECTION_LTR - mNormalSize = dp2px(18.4f) - val typedArray: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.UnreadCountTextView) - val paintColor = typedArray.getColor(R.styleable.UnreadCountTextView_paint_color, resources.getColor(R.color.app_color_read_dot_bg)) - typedArray.recycle() - - mPaint = Paint() - mPaint.color = paintColor - mPaint.isAntiAlias = true - } - - fun setPaintColor(color: Int) { - mPaint.color = color - } - - override fun onDraw(canvas: Canvas) { - when (text.length) { - 0 -> { - val l = (measuredWidth - dp2px(6f)) / 2 - val t = l - val r = measuredWidth - l - val b = r - canvas.drawOval(RectF(l.toFloat(), t.toFloat(), r.toFloat(), b.toFloat()), mPaint) - } - 1 -> { - canvas.drawOval(RectF(0f, 0f, mNormalSize.toFloat(), mNormalSize.toFloat()), mPaint) - } - else -> { - canvas.drawRoundRect( - RectF(0f, 0f, measuredWidth.toFloat(), measuredHeight.toFloat()), - measuredHeight / 2f, - measuredHeight / 2f, - mPaint - ) - } - } - super.onDraw(canvas) - } - - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - var width = mNormalSize - val height = mNormalSize - if (text.length > 1) { - width = mNormalSize + dp2px((text.length - 1) * 10f) - } - setMeasuredDimension(width, height) - } - - private fun dp2px(dp: Float): Int { - val displayMetrics: DisplayMetrics = resources.displayMetrics - return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics).toInt() - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/MultiImageData.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/MultiImageData.kt deleted file mode 100644 index 1abfe9f9..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/MultiImageData.kt +++ /dev/null @@ -1,97 +0,0 @@ -package com.tencent.uikit.app.common.widget.gatherimage - -import android.graphics.Bitmap -import android.graphics.Color -import java.util.* - -/** - * Multiple image data - */ -class MultiImageData : Cloneable { - companion object { - const val maxSize = 9 - } - - var imageUrls: MutableList? = null - var defaultImageResId: Int = 0 - var bitmapMap: MutableMap? = null - var bgColor = Color.parseColor("#cfd3d8") - - var targetImageSize: Int = 0 - var maxWidth: Int = 0 - var maxHeight: Int = 0 - var rowCount: Int = 0 - var columnCount: Int = 0 - var gap = 6 - - constructor() - - constructor(defaultImageResId: Int) { - this.defaultImageResId = defaultImageResId - } - - constructor(imageUrls: MutableList?, defaultImageResId: Int) { - this.imageUrls = imageUrls - this.defaultImageResId = defaultImageResId - } - -// fun getDefaultImageResId(): Int { -// return defaultImageResId -// } -// -// fun setDefaultImageResId(defaultImageResId: Int) { -// this.defaultImageResId = defaultImageResId -// } - -// fun getImageUrls(): MutableList? { -// return imageUrls -// } -// -// fun setImageUrls(imageUrls: MutableList?) { -// this.imageUrls = imageUrls -// } - - fun putBitmap(bitmap: Bitmap, position: Int) { - if (bitmapMap != null) { - synchronized(bitmapMap!!) { - bitmapMap!![position] = bitmap - } - } else { - bitmapMap = HashMap() - synchronized(bitmapMap!!) { - bitmapMap!![position] = bitmap - } - } - } - - fun getBitmap(position: Int): Bitmap? { - if (bitmapMap != null) { - synchronized(bitmapMap!!) { - return bitmapMap!![position] - } - } - return null - } - - fun size(): Int { - return if (imageUrls != null) { - if (imageUrls!!.size > maxSize) maxSize else imageUrls!!.size - } else { - 0 - } - } - - @Throws(CloneNotSupportedException::class) - public override fun clone(): MultiImageData { - val multiImageData = super.clone() as MultiImageData - if (imageUrls != null) { - multiImageData.imageUrls = ArrayList(imageUrls!!.size) - multiImageData.imageUrls!!.addAll(imageUrls!!) - } - if (bitmapMap != null) { - multiImageData.bitmapMap = HashMap() - multiImageData.bitmapMap!!.putAll(bitmapMap!!) - } - return multiImageData - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/ShadeImageView.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/ShadeImageView.kt deleted file mode 100644 index d045f7e3..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/ShadeImageView.kt +++ /dev/null @@ -1,80 +0,0 @@ -package com.tencent.uikit.app.common.widget.gatherimage - -import android.annotation.SuppressLint -import android.content.Context -import android.content.res.TypedArray -import android.graphics.* -import android.util.AttributeSet -import android.util.SparseArray -import android.widget.ImageView -import com.tencent.uikit.app.R -import com.trtc.tuikit.common.util.ScreenUtil - -@SuppressLint("AppCompatCustomView") -open class ShadeImageView : ImageView { - companion object { - private val sRoundBitmapArray = SparseArray() - } - - private val mShadePaint = Paint() - private var mRoundBitmap: Bitmap? = null - private var radius: Int = 0 - - constructor(context: Context) : super(context) - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { - init(context, attrs) - } - - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { - init(context, attrs) - } - - private fun init(context: Context, attrs: AttributeSet?) { - radius = ScreenUtil.dp2px(4.0f, resources.displayMetrics).toInt() - val array: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundRectImageStyle) - radius = array.getDimensionPixelSize(R.styleable.RoundRectImageStyle_round_radius, radius) - array.recycle() - setLayerType(LAYER_TYPE_HARDWARE, null) - } - - override fun onDraw(canvas: Canvas) { - super.onDraw(canvas) - mShadePaint.color = Color.RED - mShadePaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN) - mRoundBitmap = sRoundBitmapArray[measuredWidth + radius] - if (mRoundBitmap == null) { - mRoundBitmap = getRoundBitmap() - sRoundBitmapArray.put(measuredWidth + radius, mRoundBitmap) - } - canvas.drawBitmap(mRoundBitmap!!, 0f, 0f, mShadePaint) - } - - /** - * Get rounded rectangle - * - * @return Bitmap - */ - private fun getRoundBitmap(): Bitmap { - val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) - val canvas = Canvas(output) - val color = Color.parseColor("#cfd3d8") - val rect = Rect(0, 0, measuredWidth, measuredHeight) - val rectF = RectF(rect) - val paint = Paint() - paint.isAntiAlias = true - canvas.drawARGB(0, 0, 0, 0) - paint.color = color - canvas.drawRoundRect(rectF, radius.toFloat(), radius.toFloat(), paint) - return output - } - - fun getRadius(): Int { - return radius - } - - fun setRadius(radius: Int) { - this.radius = radius - invalidate() - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/SynthesizedImageView.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/SynthesizedImageView.kt deleted file mode 100644 index dc6e4113..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/SynthesizedImageView.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.tencent.uikit.app.common.widget.gatherimage - -import android.content.Context -import android.content.res.TypedArray -import android.graphics.Color -import android.util.AttributeSet -import com.tencent.uikit.app.R - -class SynthesizedImageView : ShadeImageView { - /** - * Group Chat Avatar Synthesizer - */ - private lateinit var teamHeadSynthesizer: TeamHeadSynthesizer - private var imageSize = 100 - private var synthesizedBg = Color.parseColor("#cfd3d8") - private var defaultImageResId = 0 - private var imageGap = 6 - - constructor(context: Context) : super(context) { - init(context) - } - - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { - initAttrs(attrs) - init(context) - } - - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { - initAttrs(attrs) - init(context) - } - - private fun initAttrs(attributeSet: AttributeSet?) { - val ta: TypedArray? = context.obtainStyledAttributes(attributeSet, R.styleable.SynthesizedImageView) - if (ta != null) { - synthesizedBg = ta.getColor(R.styleable.SynthesizedImageView_synthesized_image_bg, synthesizedBg) - defaultImageResId = ta.getResourceId(R.styleable.SynthesizedImageView_synthesized_default_image, defaultImageResId) - imageSize = ta.getDimensionPixelSize(R.styleable.SynthesizedImageView_synthesized_image_size, imageSize) - imageGap = ta.getDimensionPixelSize(R.styleable.SynthesizedImageView_synthesized_image_gap, imageGap) - ta.recycle() - } - } - - private fun init(context: Context) { - teamHeadSynthesizer = TeamHeadSynthesizer(context, this) - teamHeadSynthesizer.setMaxWidthHeight(imageSize, imageSize) - teamHeadSynthesizer.setDefaultImage(defaultImageResId) - teamHeadSynthesizer.setBgColor(synthesizedBg) - teamHeadSynthesizer.setGap(imageGap) - } - - fun displayImage(imageUrls: List?): SynthesizedImageView { - teamHeadSynthesizer.getMultiImageData().imageUrls=(imageUrls?.toMutableList()) - return this - } - - fun defaultImage(defaultImage: Int): SynthesizedImageView { - teamHeadSynthesizer.setDefaultImage(defaultImage) - return this - } - - fun synthesizedWidthHeight(maxWidth: Int, maxHeight: Int): SynthesizedImageView { - teamHeadSynthesizer.setMaxWidthHeight(maxWidth, maxHeight) - return this - } - - fun setImageId(id: String) { - teamHeadSynthesizer.setImageId(id) - } - - fun load(imageId: String) { - teamHeadSynthesizer.load(imageId) - } - - fun clear() { - teamHeadSynthesizer.clearImage() - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/Synthesizer.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/Synthesizer.kt deleted file mode 100644 index c8dbbcfc..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/Synthesizer.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tencent.uikit.app.common.widget.gatherimage - -import android.graphics.Bitmap -import android.graphics.Canvas - -interface Synthesizer { - fun synthesizeImageList(imageData: MultiImageData): Bitmap - fun asyncLoadImageList(imageData: MultiImageData): Boolean - fun drawDrawable(canvas: Canvas, imageData: MultiImageData) -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/TeamHeadSynthesizer.kt b/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/TeamHeadSynthesizer.kt deleted file mode 100644 index bed97f56..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/common/widget/gatherimage/TeamHeadSynthesizer.kt +++ /dev/null @@ -1,470 +0,0 @@ -package com.tencent.uikit.app.common.widget.gatherimage - -import android.content.Context -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.Canvas -import android.graphics.Rect -import android.text.TextUtils -import android.widget.ImageView -import com.tencent.qcloud.tuicore.TUIConfig -import com.tencent.uikit.app.R -import com.tencent.uikit.app.common.utils.ImageUtil -import com.tencent.uikit.app.common.utils.GlideEngine -import com.tencent.uikit.app.common.utils.ThreadUtils -import java.io.File -import java.util.* -import java.util.concurrent.ExecutionException - -class TeamHeadSynthesizer(private val mContext: Context, private val imageView: ImageView) : - Synthesizer { - private lateinit var multiImageData: MultiImageData - - // It is safe to set and get only in the main thread - private var currentImageId = "" - - private val callback = object : Callback { - override fun onCall(bitmap: Bitmap, targetID: String) { - if (!TextUtils.equals(getImageId(), targetID)) { - return - } - GlideEngine.loadUserIcon(imageView, bitmap) - } - } - - init { - init() - } - - private fun init() { - multiImageData = MultiImageData() - } - - fun setMaxWidthHeight(maxWidth: Int, maxHeight: Int) { - multiImageData.maxWidth = maxWidth - multiImageData.maxHeight = maxHeight - } - - fun getMultiImageData(): MultiImageData { - return multiImageData - } - - fun getDefaultImage(): Int { - return multiImageData.defaultImageResId - } - - fun setDefaultImage(defaultImageResId: Int) { - multiImageData.defaultImageResId = defaultImageResId - } - - fun setBgColor(bgColor: Int) { - multiImageData.bgColor = bgColor - } - - fun setGap(gap: Int) { - multiImageData.gap = gap - } - - /** - * Set Grid params - * - * @param imagesSize Number of pictures - * @return gridParam[0] Rows gridParam[1] columns - */ - protected fun calculateGridParam(imagesSize: Int): IntArray { - val gridParam = IntArray(2) - if (imagesSize < 3) { - gridParam[0] = 1 - gridParam[1] = imagesSize - } else if (imagesSize <= 4) { - gridParam[0] = 2 - gridParam[1] = 2 - } else { - gridParam[0] = imagesSize / 3 + if (imagesSize % 3 == 0) 0 else 1 - gridParam[1] = 3 - } - return gridParam - } - - override fun synthesizeImageList(imageData: MultiImageData): Bitmap { - val mergeBitmap = - Bitmap.createBitmap(imageData.maxWidth, imageData.maxHeight, Bitmap.Config.ARGB_8888) - val canvas = Canvas(mergeBitmap) - drawDrawable(canvas, imageData) - canvas.save() - canvas.restore() - return mergeBitmap - } - - override fun asyncLoadImageList(imageData: MultiImageData): Boolean { - val loadSuccess = true - val imageUrls = imageData.imageUrls - if (imageUrls != null) { - for (i in imageUrls.indices) { - val defaultIcon = - BitmapFactory.decodeResource( - mContext.resources, - R.drawable.app_default_user_icon_light - ) - try { - val bitmap = asyncLoadImage(imageUrls[i], imageData.targetImageSize) - imageData.putBitmap(bitmap, i) - } catch (e: InterruptedException) { - e.printStackTrace() - imageData.putBitmap(defaultIcon, i) - } catch (e: ExecutionException) { - e.printStackTrace() - imageData.putBitmap(defaultIcon, i) - } - } - } - return loadSuccess - } - - override fun drawDrawable(canvas: Canvas, imageData: MultiImageData) { - canvas.drawColor(imageData.bgColor) - val size = imageData.size() - val tCenter = (imageData.maxHeight + imageData.gap) / 2 - val bCenter = (imageData.maxHeight - imageData.gap) / 2 - val lCenter = (imageData.maxWidth + imageData.gap) / 2 - val rCenter = (imageData.maxWidth - imageData.gap) / 2 - val center = (imageData.maxHeight - imageData.targetImageSize) / 2 - - for (i in 0 until size) { - val rowNum = i / imageData.columnCount - val columnNum = i % imageData.columnCount - - val left = - (imageData.targetImageSize * (if (imageData.columnCount == 1) columnNum + 0.5 else columnNum.toDouble()) + imageData.gap * (columnNum + 1)).toInt() - val top = - (imageData.targetImageSize * (if (imageData.columnCount == 1) rowNum + 0.5 else rowNum.toDouble()) + imageData.gap * (rowNum + 1)).toInt() - val right = left + imageData.targetImageSize - val bottom = top + imageData.targetImageSize - - val bitmap = imageData.getBitmap(i) - when (size) { - 1 -> { - drawBitmapAtPosition(canvas, left, top, right, bottom, bitmap) - } - - 2 -> { - drawBitmapAtPosition( - canvas, - left, - center, - right, - center + imageData.targetImageSize, - bitmap - ) - } - - 3 -> { - if (i == 0) { - drawBitmapAtPosition( - canvas, - center, - top, - center + imageData.targetImageSize, - bottom, - bitmap - ) - } else { - drawBitmapAtPosition( - canvas, - imageData.gap * i + imageData.targetImageSize * (i - 1), - tCenter, - imageData.gap * i + imageData.targetImageSize * i, - tCenter + imageData.targetImageSize, - bitmap - ) - } - } - - 4 -> { - drawBitmapAtPosition(canvas, left, top, right, bottom, bitmap) - } - - 5 -> { - when (i) { - 0 -> { - drawBitmapAtPosition( - canvas, - rCenter - imageData.targetImageSize, - rCenter - imageData.targetImageSize, - rCenter, - rCenter, - bitmap - ) - } - - 1 -> { - drawBitmapAtPosition( - canvas, - lCenter, - rCenter - imageData.targetImageSize, - lCenter + imageData.targetImageSize, - rCenter, - bitmap - ) - } - - else -> { - drawBitmapAtPosition( - canvas, - imageData.gap * (i - 1) + imageData.targetImageSize * (i - 2), - tCenter, - imageData.gap * (i - 1) + imageData.targetImageSize * (i - 1), - tCenter + imageData.targetImageSize, - bitmap - ) - } - } - } - - 6 -> { - if (i < 3) { - drawBitmapAtPosition( - canvas, - imageData.gap * (i + 1) + imageData.targetImageSize * i, - bCenter - imageData.targetImageSize, - imageData.gap * (i + 1) + imageData.targetImageSize * (i + 1), - bCenter, - bitmap - ) - } else { - drawBitmapAtPosition( - canvas, - imageData.gap * (i - 2) + imageData.targetImageSize * (i - 3), - tCenter, - imageData.gap * (i - 2) + imageData.targetImageSize * (i - 2), - tCenter + imageData.targetImageSize, - bitmap - ) - } - } - - 7 -> { - when { - i == 0 -> { - drawBitmapAtPosition( - canvas, - center, - imageData.gap, - center + imageData.targetImageSize, - imageData.gap + imageData.targetImageSize, - bitmap - ) - } - - i in 1..3 -> { - drawBitmapAtPosition( - canvas, - imageData.gap * i + imageData.targetImageSize * (i - 1), - center, - imageData.gap * i + imageData.targetImageSize * i, - center + imageData.targetImageSize, - bitmap - ) - } - - else -> { - drawBitmapAtPosition( - canvas, - imageData.gap * (i - 3) + imageData.targetImageSize * (i - 4), - tCenter + imageData.targetImageSize / 2, - imageData.gap * (i - 3) + imageData.targetImageSize * (i - 3), - tCenter + imageData.targetImageSize / 2 + imageData.targetImageSize, - bitmap - ) - } - } - } - - 8 -> { - when { - i == 0 -> { - drawBitmapAtPosition( - canvas, - rCenter - imageData.targetImageSize, - imageData.gap, - rCenter, - imageData.gap + imageData.targetImageSize, - bitmap - ) - } - - i == 1 -> { - drawBitmapAtPosition( - canvas, - lCenter, - imageData.gap, - lCenter + imageData.targetImageSize, - imageData.gap + imageData.targetImageSize, - bitmap - ) - } - - i in 2..4 -> { - drawBitmapAtPosition( - canvas, - imageData.gap * (i - 1) + imageData.targetImageSize * (i - 2), - center, - imageData.gap * (i - 1) + imageData.targetImageSize * (i - 1), - center + imageData.targetImageSize, - bitmap - ) - } - - else -> { - drawBitmapAtPosition( - canvas, - imageData.gap * (i - 4) + imageData.targetImageSize * (i - 5), - tCenter + imageData.targetImageSize / 2, - imageData.gap * (i - 4) + imageData.targetImageSize * (i - 4), - tCenter + imageData.targetImageSize / 2 + imageData.targetImageSize, - bitmap - ) - } - } - } - - 9 -> { - drawBitmapAtPosition(canvas, left, top, right, bottom, bitmap) - } - } - } - } - - /** - * DrawBitmap - * - * @param canvas - * @param left - * @param top - * @param right - * @param bottom - * @param bitmap - */ - fun drawBitmapAtPosition( - canvas: Canvas, - left: Int, - top: Int, - right: Int, - bottom: Int, - bitmap: Bitmap? - ) { - var drawBitmap = bitmap - if (drawBitmap == null) { - if (multiImageData.defaultImageResId > 0) { - drawBitmap = - BitmapFactory.decodeResource( - mContext.resources, - multiImageData.defaultImageResId - ) - } - } - if (drawBitmap != null) { - val rect = Rect(left, top, right, bottom) - canvas.drawBitmap(drawBitmap, null, rect, null) - } - } - - @Throws(ExecutionException::class, InterruptedException::class) - private fun asyncLoadImage(imageUrl: Any, targetImageSize: Int): Bitmap { - return GlideEngine.loadBitmap(imageUrl, targetImageSize) - } - - fun setImageId(id: String) { - currentImageId = id - } - - fun getImageId(): String { - return currentImageId - } - - fun load(imageId: String?) { - if (multiImageData.size() == 0) { - // The image id when the request is initiated is inconsistent with the current image id, - // indicating that multiplexing has occurred, and the image should not be set at this time. - if (imageId != null && !TextUtils.equals(imageId, currentImageId)) { - return - } - GlideEngine.loadUserIcon(imageView, getDefaultImage()) - return - } - - if (multiImageData.size() == 1) { - // The image id when the request is initiated is inconsistent with the current image id, - // indicating that multiplexing has occurred, and the image should not be set at this time. - if (imageId != null && !TextUtils.equals(imageId, currentImageId)) { - return - } - GlideEngine.loadUserIcon(imageView, multiImageData.imageUrls!![0]) - return - } - - // Clear the content before loading images asynchronously to avoid flickering - clearImage() - - // Initialize the image information. Since it is asynchronous loading and synthesizing the avatar, - // a local object needs to be passed to the synthesis thread, which is only used in the asynchronous - // loading thread, so that when the image is reused, the external thread will not overwrite the local - // object by setting the url again. - var copyMultiImageData: MultiImageData - try { - copyMultiImageData = multiImageData.clone() - } catch (e: CloneNotSupportedException) { - e.printStackTrace() - val urlList = ArrayList() - if (multiImageData.imageUrls != null) { - urlList.addAll(multiImageData.imageUrls!!) - } - copyMultiImageData = MultiImageData(urlList, multiImageData.defaultImageResId) - } - - val gridParam = calculateGridParam(multiImageData.size()) - copyMultiImageData.rowCount = gridParam[0] - copyMultiImageData.columnCount = gridParam[1] - copyMultiImageData.targetImageSize = - (copyMultiImageData.maxWidth - (copyMultiImageData.columnCount + 1) * copyMultiImageData.gap) / - if (copyMultiImageData.columnCount == 1) 2 else copyMultiImageData.columnCount - - val finalImageId = imageId - val finalCopyMultiImageData = copyMultiImageData - - ThreadUtils.execute { - val file = File(TUIConfig.getImageBaseDir() + finalImageId) - var cacheBitmapExists = false - var existsBitmap: Bitmap? = null - if (file.exists() && file.isFile) { - val options = BitmapFactory.Options() - existsBitmap = BitmapFactory.decodeFile(file.path, options) - if (options.outWidth > 0 && options.outHeight > 0) { - cacheBitmapExists = true - } - } - if (!cacheBitmapExists) { - asyncLoadImageList(finalCopyMultiImageData) - val bitmap = synthesizeImageList(finalCopyMultiImageData) - ImageUtil.storeBitmap(file, bitmap) - ImageUtil.setGroupConversationAvatar(finalImageId!!, file.absolutePath) - ThreadUtils.postOnUiThread { - callback.onCall(bitmap, finalImageId) - } - } else { - val finalExistsBitmap = existsBitmap - ThreadUtils.postOnUiThread { - callback.onCall(finalExistsBitmap!!, finalImageId!!) - } - } - } - } - - fun clearImage() { - GlideEngine.clear(imageView) - } - - internal interface Callback { - fun onCall(bitmap: Bitmap, targetID: String) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/login/LocalMusicService.kt b/application/app/src/main/java/com/tencent/uikit/app/login/LocalMusicService.kt deleted file mode 100644 index 879ffe86..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/login/LocalMusicService.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.tencent.uikit.app.login - -import com.trtc.uikit.livekit.component.karaoke.store.ActionCallback -import com.trtc.uikit.livekit.component.karaoke.store.GetSongListCallBack -import com.trtc.uikit.livekit.component.karaoke.store.MusicCatalogService -import com.trtc.uikit.livekit.component.karaoke.store.utils.MusicInfo -import com.tencent.qcloud.tuikit.debug.GenerateTestUserSig - -class LocalMusicService : MusicCatalogService() { - - override fun getSongList(callback: GetSongListCallBack) { - val localList = ArrayList() - callback.onSuccess(localList) - } - - override fun generateUserSig( - userId: String, - callback: ActionCallback, - ) { - callback.onSuccess(GenerateTestUserSig.genTestUserSig(userId)) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/login/LoginActivity.kt b/application/app/src/main/java/com/tencent/uikit/app/login/LoginActivity.kt deleted file mode 100644 index 3ef13077..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/login/LoginActivity.kt +++ /dev/null @@ -1,108 +0,0 @@ -package com.tencent.uikit.app.login - -import android.content.Intent -import android.os.Bundle -import android.util.Log -import android.view.View -import android.widget.EditText -import androidx.lifecycle.lifecycleScope -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.qcloud.tuicore.util.SPUtils -import com.tencent.qcloud.tuikit.debug.GenerateTestUserSig -import com.tencent.qcloud.tuikit.tuicallkit.TUICallKit.Companion.createInstance -import com.tencent.uikit.app.R -import com.tencent.uikit.app.common.utils.DEMO_LOGIN_SUCCESS -import com.tencent.uikit.app.common.utils.KeyMetrics -import com.tencent.uikit.app.main.BaseActivity -import com.tencent.uikit.app.main.MainActivity -import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast -import io.trtc.tuikit.atomicxcore.api.CompletionHandler -import io.trtc.tuikit.atomicxcore.api.login.LoginStore -import kotlinx.coroutines.launch - -class LoginActivity : BaseActivity() { - companion object { - private const val TAG = "LoginActivity" - } - - private lateinit var editUserId: EditText - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - if (!isTaskRoot - && intent.hasCategory(Intent.CATEGORY_LAUNCHER) - && intent.action != null - && intent.action.equals(Intent.ACTION_MAIN) - ) { - finish() - return - } - setContentView(R.layout.app_activity_login) - initView() - } - - private fun initView() { - editUserId = findViewById(R.id.et_userId) - editUserId.setText(SPUtils.getInstance("app_uikit").getString("userId")) - findViewById(R.id.btn_login).setOnClickListener { - val userId = editUserId.text.toString().trim() - SPUtils.getInstance("app_uikit").put("userId", userId) - login(userId) - } - } - - private fun login(userId: String) { - if (userId.isEmpty()) { - AtomicToast.show( - this, - getString(R.string.app_user_id_is_empty), - AtomicToast.Style.ERROR - ) - return - } - val userSig = GenerateTestUserSig.genTestUserSig(userId) - LoginStore.shared.login(this, GenerateTestUserSig.SDKAPPID, userId, userSig, object : CompletionHandler { - override fun onSuccess() { - Log.i(TAG, "login onSuccess") - val instance = createInstance(application) - instance.enableFloatWindow(true) - instance.enableVirtualBackground(true) - instance.enableIncomingBanner(true) - instance.enableAITranscriber(true) - getUserInfo() - - KeyMetrics.reportAtomicMetrics(DEMO_LOGIN_SUCCESS) - } - - override fun onFailure(code: Int, desc: String) { - AtomicToast.show( - this@LoginActivity, - getString(R.string.app_toast_login_fail, code, desc), - AtomicToast.Style.ERROR - ) - Log.e(TAG, "login fail errorCode: $code errorMessage:$desc") - } - }) - TUILogin.login(this, GenerateTestUserSig.SDKAPPID, userId, userSig, null) - } - - private fun getUserInfo() { - lifecycleScope.launch { - LoginStore.shared.loginState.loginUserInfo.collect { loginUserInfo -> - loginUserInfo?.let { - if (it.userID.isEmpty()) { - return@collect - } - if (it.nickname.isNullOrEmpty() || it.avatarURL.isNullOrEmpty()) { - val intent = Intent(this@LoginActivity, RegisterActivity::class.java) - startActivity(intent) - finish() - } else { - val intent = Intent(this@LoginActivity, MainActivity::class.java) - startActivity(intent) - finish() - } - } - } - } - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/login/RegisterActivity.kt b/application/app/src/main/java/com/tencent/uikit/app/login/RegisterActivity.kt deleted file mode 100644 index 05c50ec0..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/login/RegisterActivity.kt +++ /dev/null @@ -1,164 +0,0 @@ -package com.tencent.uikit.app.login - -import android.content.Intent -import android.os.Bundle -import android.text.Editable -import android.text.TextWatcher -import android.util.Log -import android.widget.Button -import android.widget.EditText -import android.widget.TextView -import androidx.core.content.ContextCompat -import com.tencent.imsdk.v2.V2TIMCallback -import com.tencent.imsdk.v2.V2TIMUserFullInfo -import com.tencent.uikit.app.R -import com.tencent.uikit.app.main.BaseActivity -import com.tencent.uikit.app.main.MainActivity -import com.tencent.uikit.app.mine.UserManager -import io.trtc.tuikit.atomicx.widget.basicwidget.avatar.AtomicAvatar -import io.trtc.tuikit.atomicx.widget.basicwidget.avatar.AtomicAvatar.AvatarContent -import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast -import java.util.Random -import java.util.regex.Pattern - -class RegisterActivity : BaseActivity() { - companion object { - private const val TAG = "RegisterActivity" - - private val USER_AVATAR_ARRAY = arrayOf( - "https://liteav.sdk.qcloud.com/app/res/picture/voiceroom/avatar/user_avatar1.png", - "https://liteav.sdk.qcloud.com/app/res/picture/voiceroom/avatar/user_avatar2.png", - "https://liteav.sdk.qcloud.com/app/res/picture/voiceroom/avatar/user_avatar3.png", - "https://liteav.sdk.qcloud.com/app/res/picture/voiceroom/avatar/user_avatar4.png", - "https://liteav.sdk.qcloud.com/app/res/picture/voiceroom/avatar/user_avatar5.png" - ) - - private val CUSTOM_NAME_ARRAY = arrayOf( - R.string.app_custom_name_1, - R.string.app_custom_name_2, - R.string.app_custom_name_3, - R.string.app_custom_name_4, - R.string.app_custom_name_5 - ) - } - - private lateinit var imageAvatar: AtomicAvatar - private lateinit var editUserName: EditText - private lateinit var buttonRegister: Button - private lateinit var tvInputTips: TextView - private var avatarUrl: String = "" - private val random = Random() - - private fun startMainActivity() { - val intent = Intent(this@RegisterActivity, MainActivity::class.java) - startActivity(intent) - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.app_activity_login_profile) - initView() - } - - private fun initView() { - imageAvatar = findViewById(R.id.iv_user_avatar) - editUserName = findViewById(R.id.et_user_name) - buttonRegister = findViewById(R.id.btn_register) - tvInputTips = findViewById(R.id.tv_tips_user_name) - - val index = random.nextInt(USER_AVATAR_ARRAY.size) - avatarUrl = USER_AVATAR_ARRAY[index] - imageAvatar.setContent(AvatarContent.URL(avatarUrl, R.drawable.app_avatar)) - - buttonRegister.setOnClickListener { - setProfile() - } - - val customNameIndex = random.nextInt(CUSTOM_NAME_ARRAY.size) - editUserName.setText(getString(CUSTOM_NAME_ARRAY[customNameIndex])) - val text = editUserName.text.toString() - if (text.isNotEmpty()) { - editUserName.setSelection(text.length) - } - - editUserName.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - buttonRegister.isEnabled = !s.isNullOrEmpty() - val editable = editUserName.text.toString() - val pattern = Pattern.compile("^[a-z0-9A-Z\\u4e00-\\u9fa5\\_]{2,20}$") - val matcher = pattern.matcher(editable) - if (!matcher.matches()) { - tvInputTips.setTextColor( - ContextCompat.getColor( - this@RegisterActivity, - R.color.app_color_input_no_match - ) - ) - } else { - tvInputTips.setTextColor( - ContextCompat.getColor( - this@RegisterActivity, - R.color.app_text_color_hint - ) - ) - } - } - - override fun afterTextChanged(s: Editable?) {} - }) - } - - private fun setProfile() { - val userName = editUserName.text.toString().trim() - if (userName.isEmpty()) { - AtomicToast.show( - this, - getString(R.string.app_hint_user_name), - AtomicToast.Style.ERROR, - duration = AtomicToast.Duration.LONG - ) - return - } - val reg = "^[a-z0-9A-Z\\u4e00-\\u9fa5\\_]{2,20}$" - if (!userName.matches(reg.toRegex())) { - tvInputTips.setTextColor( - ContextCompat.getColor( - this, - R.color.app_color_input_no_match - ) - ) - return - } - tvInputTips.setTextColor(ContextCompat.getColor(this, R.color.app_text_color_hint)) - val v2TIMUserFullInfo = V2TIMUserFullInfo() - v2TIMUserFullInfo.setFaceUrl(avatarUrl) - v2TIMUserFullInfo.setNickname(userName) - UserManager.getInstance().updateSelfUserInfo(v2TIMUserFullInfo, object : V2TIMCallback { - override fun onError(code: Int, desc: String?) { - Log.e(TAG, "set profile failed errorCode : $code errorMsg : $desc") - AtomicToast.show( - this@RegisterActivity, - getString(R.string.app_toast_failed_to_set, desc), - AtomicToast.Style.ERROR, - duration = AtomicToast.Duration.LONG - ) - startMainActivity() - finish() - } - - override fun onSuccess() { - Log.i(TAG, "set profile success.") - AtomicToast.show( - this@RegisterActivity, - getString(R.string.app_toast_register_success_and_logging_in), - AtomicToast.Style.SUCCESS, - duration = AtomicToast.Duration.LONG - ) - startMainActivity() - finish() - } - }) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/BaseActivity.kt b/application/app/src/main/java/com/tencent/uikit/app/main/BaseActivity.kt deleted file mode 100644 index 15c2e321..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/BaseActivity.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.tencent.uikit.app.main - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.graphics.Color -import android.os.Build -import android.os.Bundle -import android.view.MotionEvent -import android.view.View -import android.view.WindowManager -import android.view.inputmethod.InputMethodManager -import androidx.appcompat.app.AppCompatActivity -import androidx.localbroadcastmanager.content.LocalBroadcastManager -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.qcloud.tuicore.util.TUIBuild -import com.tencent.uikit.app.login.LoginActivity -import com.tencent.uikit.app.setting.LanguageSelectActivity - -open class BaseActivity : AppCompatActivity() { - - private val languageChangedReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - if (intent?.action == LanguageSelectActivity.LANGUAGE_CHANGED_ACTION) { - recreate() - } - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - checkUserLoginStatus(savedInstanceState) - initStatusBar() - hideSoftKeyboard() - - LocalBroadcastManager.getInstance(this).registerReceiver( - languageChangedReceiver, - IntentFilter(LanguageSelectActivity.LANGUAGE_CHANGED_ACTION) - ) - } - - private fun checkUserLoginStatus(savedInstanceState: Bundle?) { - if (savedInstanceState != null && !TUILogin.isUserLogined()) { - val loginIntent = Intent(this, LoginActivity::class.java).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) - } - startActivity(loginIntent) - finish() - } - } - - override fun onTouchEvent(event: MotionEvent?): Boolean { - try { - val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - currentFocus?.windowToken?.let { - imm.hideSoftInputFromWindow(it, 0) - } - } catch (_: Exception) { - } - return super.onTouchEvent(event) - } - - private fun initStatusBar() { - val window = window - if (TUIBuild.getVersionInt() >= Build.VERSION_CODES.LOLLIPOP) { - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) - window.decorView.systemUiVisibility = - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) - window.statusBarColor = Color.TRANSPARENT - } else if (TUIBuild.getVersionInt() >= Build.VERSION_CODES.KITKAT) { - window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) - } - } - - protected fun hideSoftKeyboard() { - window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) - } - - override fun onDestroy() { - runCatching { - LocalBroadcastManager.getInstance(this).unregisterReceiver(languageChangedReceiver) - } - super.onDestroy() - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/MainActivity.kt b/application/app/src/main/java/com/tencent/uikit/app/main/MainActivity.kt deleted file mode 100644 index 30412fc4..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/MainActivity.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.tencent.uikit.app.main - -import android.content.Intent -import android.os.Bundle -import android.util.Log -import androidx.navigation.NavController -import androidx.navigation.Navigation -import androidx.navigation.fragment.NavHostFragment -import com.tencent.imsdk.v2.V2TIMUserFullInfo -import com.tencent.imsdk.v2.V2TIMValueCallback -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.uikit.app.R -import com.tencent.uikit.app.common.widget.RecycleFragmentNavigator -import com.tencent.uikit.app.login.LoginActivity -import com.tencent.uikit.app.mine.UserManager - - -class MainActivity : BaseActivity() { - companion object { - private const val TAG = "MainActivity" - } - - private var mNavController: NavController? = null - - public override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.app_activity_trtc_main) - - - mNavController = Navigation.findNavController(this, R.id.nav_host_fragment) - val navHostFragment: NavHostFragment? = - supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment? - val recycleFragmentNavigator: RecycleFragmentNavigator = RecycleFragmentNavigator( - this, - supportFragmentManager, navHostFragment?.getId() ?: 0 - ) - mNavController?.navigatorProvider?.addNavigator(recycleFragmentNavigator) - mNavController?.setGraph(R.navigation.app_nav_main_graph) - } - - override fun onResume() { - super.onResume() - getUserInfo() - } - - private fun getUserInfo() { - if (!TUILogin.isUserLogined()) { - val intent = Intent(this@MainActivity, LoginActivity::class.java) - startActivity(intent) - finish() - return - } - UserManager.getInstance().getSelfUserInfo(object : V2TIMValueCallback { - override fun onError(errorCode: Int, errorMsg: String?) { - Log.e(TAG, "getUserInfo failed, code:$errorCode msg: $errorMsg") - } - - override fun onSuccess(timUserFullInfo: V2TIMUserFullInfo?) { - if (timUserFullInfo == null) { - Log.e(TAG, "getUserInfo result is empty") - return - } - } - }) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/MainFragment.kt b/application/app/src/main/java/com/tencent/uikit/app/main/MainFragment.kt deleted file mode 100644 index 6c2ea043..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/MainFragment.kt +++ /dev/null @@ -1,145 +0,0 @@ -package com.tencent.uikit.app.main - -import android.content.Intent -import android.os.Bundle -import android.text.TextUtils -import android.util.Log -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.fragment.app.Fragment -import androidx.navigation.Navigation -import androidx.recyclerview.widget.GridLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.tencent.qcloud.tuicore.TUIConstants -import com.tencent.qcloud.tuicore.TUICore -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.qcloud.tuicore.TUIThemeManager -import com.tencent.qcloud.tuicore.interfaces.ITUINotification -import com.tencent.uikit.app.R -import com.tencent.uikit.app.common.utils.KeyMetrics -import io.trtc.tuikit.atomicx.widget.basicwidget.avatar.AtomicAvatar -import io.trtc.tuikit.atomicx.widget.basicwidget.avatar.AtomicAvatar.AvatarContent - -class MainFragment : Fragment() { - private var userCenter: AtomicAvatar? = null - private var recyclerMain: RecyclerView? = null - private var trtcMainAdapter: TRTCMainAdapter? = null - private val notification: ITUINotification = object : ITUINotification { - override fun onNotifyEvent(key: String?, subKey: String?, param: MutableMap) { - Log.i(TAG, "key=$key,subKey=$subKey,param=$param") - if (TextUtils.equals(param[TUIConstants.TUILogin.SELF_ID] as String?, TUILogin.getLoginUser())) { - userCenter?.setContent(AvatarContent.URL(TUILogin.getFaceUrl(), R.drawable.app_ic_avatar)) - } - } - } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val rootView: View = inflater.inflate(R.layout.app_fragment_main, container, false) - initView(rootView) - registerEvent() - return rootView - } - - override fun onDestroyView() { - super.onDestroyView() - unRegisterEvent() - } - - private fun initView(rootView: View) { - val mainTitle = rootView.findViewById(R.id.img_main_icon) - recyclerMain = rootView.findViewById(R.id.rv_main_list) - mainTitle?.setBackgroundResource(R.drawable.app_title_zh) - if (TextUtils.equals(TUIThemeManager.getInstance().currentLanguage, "en")) { - mainTitle?.setBackgroundResource(R.drawable.app_title_en) - } - userCenter = rootView.findViewById(R.id.img_user_center) - userCenter?.setContent(AvatarContent.URL(TUILogin.getFaceUrl(), R.drawable.app_ic_avatar)) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - val navController = Navigation.findNavController(view) - userCenter?.setOnClickListener { v: View? -> navController.navigate(R.id.mine_fragment) } - val trtcMainData = TRTCMainData() - trtcMainAdapter = TRTCMainAdapter( - TUIThemeManager.getInstance().currentLanguage, - trtcMainData.itemDataList as MutableList, object : TRTCMainAdapter.OnItemClickListener { - override fun onItemClick(mainItemData: MainItemData?) { - mainItemData?.let { item -> - item.itemType?.let { data -> - KeyMetrics.reportAtomicMetrics(data.reportEvent) - } - val type: Int = item.itemType?.type ?: 0 - val intent = Intent(context, item.itemTargetClass) - intent.putExtra("TITLE", getString(item.itemTitle)) - intent.putExtra("TYPE", type) - startActivity(intent) - } - } - }) - val gridLayoutManager = GridLayoutManager(getContext(), 2) - recyclerMain?.setLayoutManager(gridLayoutManager) - recyclerMain?.setAdapter(trtcMainAdapter) - } - - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - userCenter?.setContent(AvatarContent.URL(TUILogin.getFaceUrl(), R.drawable.app_ic_avatar)) - } - - private fun registerEvent() { - TUICore.registerEvent( - TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED, - TUIConstants.TUILogin.EVENT_SUB_KEY_USER_INFO_UPDATED, notification - ) - } - - private fun unRegisterEvent() { - TUICore.unRegisterEvent( - TUIConstants.TUILogin.EVENT_LOGIN_STATE_CHANGED, - TUIConstants.TUILogin.EVENT_SUB_KEY_USER_INFO_UPDATED, notification - ) - } - - companion object { - private const val TAG = "MainFragment" - const val url = "https://cloud.tencent.com/act/event/report-platform" - - } - - private data class SimpleItem( - val iconRes: Int, - val title: String, - val subtitle: String - ) - - private class SimpleAdapter( - private val items: List, - private val onItemClick: () -> Unit - ) : RecyclerView.Adapter() { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleVH { - val view = LayoutInflater.from(parent.context).inflate(R.layout.app_main_item, parent, false) - return SimpleVH(view) - } - - override fun onBindViewHolder(holder: SimpleVH, position: Int) { - val item = items[position] - holder.icon.setImageResource(item.iconRes) - holder.title.text = item.title - holder.subtitle.text = item.subtitle - holder.itemView.setOnClickListener { onItemClick() } - } - - override fun getItemCount(): Int = items.size - - class SimpleVH(itemView: View) : RecyclerView.ViewHolder(itemView) { - val icon: ImageView = itemView.findViewById(R.id.img_main_icon) - val title: TextView = itemView.findViewById(R.id.tv_main_title) - val subtitle: TextView = itemView.findViewById(R.id.tv_main_subtitle) - } - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/MainItemData.kt b/application/app/src/main/java/com/tencent/uikit/app/main/MainItemData.kt deleted file mode 100644 index f4f13dd0..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/MainItemData.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tencent.uikit.app.main - -data class MainItemData( - val itemType: MainTypeEnum?, - val itemResId: Int, - val itemTitle: Int, - val itemSubTitle: Int, - val itemTargetClass: Class<*>?, - val category: Category? -) { - enum class Category { - UNDEFINED, - KIT, - HOT - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/MainTypeEnum.kt b/application/app/src/main/java/com/tencent/uikit/app/main/MainTypeEnum.kt deleted file mode 100644 index 82468aaf..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/MainTypeEnum.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tencent.uikit.app.main - -import com.tencent.uikit.app.common.utils.DEMO_CLICK_CALL -import com.tencent.uikit.app.common.utils.DEMO_CLICK_LIVE -import com.tencent.uikit.app.common.utils.DEMO_CLICK_ROOM - -enum class MainTypeEnum(val type: Int, val properties: String, val reportEvent: Int = -1) { - TYPE_ITEM_MEETING(100, "conference", DEMO_CLICK_ROOM), - TYPE_ITEM_CALL(104, "call", DEMO_CLICK_CALL), - TYPE_ITEM_LIVE(106, "live", DEMO_CLICK_LIVE), - TYPE_ITEM_VOICE(107, "voice"), - TYPE_ITEM_CHAT(109, "chat") -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainAdapter.kt b/application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainAdapter.kt deleted file mode 100644 index 46ae534a..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainAdapter.kt +++ /dev/null @@ -1,146 +0,0 @@ -package com.tencent.uikit.app.main - -import android.content.res.Resources -import android.text.TextUtils -import android.util.TypedValue -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.TextView -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.recyclerview.widget.RecyclerView -import com.tencent.uikit.app.R - -class TRTCMainAdapter( - private val currentLanguage: String?, - private val itemDataList: MutableList, - private val onItemClickListener: OnItemClickListener -) : RecyclerView.Adapter() { - - override fun getItemViewType(position: Int): Int { - if (position == itemCount - 1) { - return ITEM_TYPE_FOOTER - } - return ITEM_TYPE_ITEM - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val context = parent.context - val inflater = LayoutInflater.from(context) - if (viewType == ITEM_TYPE_ITEM) { - val view: View = inflater.inflate(R.layout.app_main_item, parent, false) - return ItemViewHolder(view) - } else if (viewType == ITEM_TYPE_WEB_VIEW) { - val view: View = inflater.inflate(R.layout.app_item_web_view, parent, false) - return WebViewHolder(view) - } else { - val view = View(parent.context) - return FooterViewHolder(view) - } - } - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - if (holder is ItemViewHolder) { - val item: MainItemData? = itemDataList[position] - holder.bind(item, onItemClickListener) - } else if (holder is WebViewHolder) { - val item: MainItemData? = itemDataList[position] - holder.bind(item, currentLanguage, onItemClickListener) - } - } - - override fun getItemCount(): Int { - return itemDataList.size + 1 - } - - interface OnItemClickListener { - fun onItemClick(mainItemData: MainItemData?) - } - - class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - private val imageIcon: ImageView = itemView.findViewById(R.id.img_main_icon) - private val textTitle: TextView = itemView.findViewById(R.id.tv_main_title) - private val textSubTitle: TextView = itemView.findViewById(R.id.tv_main_subtitle) - private val constraintItem: ConstraintLayout = itemView.findViewById(R.id.cl_main_item) - - fun bind( - mainItemData: MainItemData?, - onItemClickListener: OnItemClickListener - ) { - if (mainItemData == null) { - return - } - itemView.setOnClickListener { v: View? -> - onItemClickListener.onItemClick( - mainItemData - ) - } - - constraintItem.setBackgroundResource( - if (mainItemData.category === MainItemData.Category.KIT) - R.drawable.app_bg_main_kit_item - else - R.drawable.app_bg_main_item - ) - textTitle.setText(mainItemData.itemTitle) - imageIcon.setImageResource(mainItemData.itemResId) - textSubTitle.setText(mainItemData.itemSubTitle) - } - } - - class WebViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - private val textTitle: TextView = itemView.findViewById(R.id.tv_main_title) - private val textSubTitle: TextView = itemView.findViewById(R.id.tv_main_subtitle) - - fun bind( - mainItemData: MainItemData?, - currentLanguage: String?, - onItemClickListener: OnItemClickListener - ) { - if (mainItemData == null) { - return - } - val layoutParams: ViewGroup.LayoutParams? - if (TextUtils.equals(currentLanguage, ENGLISH_LANGUAGE_CODE)) { - layoutParams = LinearLayout.LayoutParams( - dp2px(ENGLISH_TEXT_WIDTH_DP.toFloat()), - dp2px(ENGLISH_TEXT_HEIGHT_DP.toFloat()) - ) - } else { - layoutParams = LinearLayout.LayoutParams( - dp2px(DEFAULT_TEXT_WIDTH_DP.toFloat()), - dp2px(DEFAULT_TEXT_HEIGHT_DP.toFloat()) - ) - } - itemView.setOnClickListener(View.OnClickListener { v: View? -> - onItemClickListener.onItemClick( - mainItemData - ) - }) - textTitle.setText(mainItemData.itemTitle) - textSubTitle.setText(mainItemData.itemSubTitle) - } - } - - class FooterViewHolder(view: View) : RecyclerView.ViewHolder(view) - companion object { - const val ITEM_TYPE_ITEM: Int = 0 - const val ITEM_TYPE_FOOTER: Int = 1 - const val ITEM_TYPE_WEB_VIEW: Int = 2 - private const val ENGLISH_LANGUAGE_CODE = "en" - private const val ENGLISH_TEXT_WIDTH_DP = 36 - private const val ENGLISH_TEXT_HEIGHT_DP = 18 - private const val DEFAULT_TEXT_WIDTH_DP = 32 - private const val DEFAULT_TEXT_HEIGHT_DP = 18 - private fun dp2px(dp: Float): Int { - return TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - dp, - Resources.getSystem().displayMetrics - ) - .toInt() - } - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainData.kt b/application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainData.kt deleted file mode 100644 index 82b9fef5..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/TRTCMainData.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.tencent.uikit.app.main - -import com.tencent.uikit.app.R -import com.tencent.uikit.app.main.call.GroupCallActivity -import com.tencent.uikit.app.main.live.LiveActivity -import com.trtc.uikit.roomkit.RoomHomeActivity - -class TRTCMainData { - val itemDataList = ArrayList() - - init { - itemDataList.add( - MainItemData( - MainTypeEnum.TYPE_ITEM_CALL, R.drawable.app_ic_main_call, R.string.app_main_item_call, - R.string.app_main_item_call_sub, GroupCallActivity::class.java, MainItemData.Category.KIT - ) - ) - itemDataList.add( - MainItemData( - MainTypeEnum.TYPE_ITEM_LIVE, R.drawable.app_ic_main_live, R.string.app_main_item_live, - R.string.app_main_item_live_sub, LiveActivity::class.java, MainItemData.Category.KIT - ) - ) - itemDataList.add( - MainItemData( - MainTypeEnum.TYPE_ITEM_MEETING, R.drawable.app_ic_main_meeting, R.string.app_main_item_meeting, - R.string.app_main_item_meeting_sub, RoomHomeActivity::class.java, MainItemData.Category.KIT - ) - ) - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/call/GroupCallActivity.kt b/application/app/src/main/java/com/tencent/uikit/app/main/call/GroupCallActivity.kt deleted file mode 100644 index d5192e60..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/call/GroupCallActivity.kt +++ /dev/null @@ -1,102 +0,0 @@ -package com.tencent.uikit.app.main.call - -import android.content.Intent -import android.os.Bundle -import android.text.TextUtils -import android.view.View -import android.widget.EditText -import android.widget.RadioGroup -import android.widget.RelativeLayout -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.qcloud.tuikit.tuicallkit.TUICallKit -import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast -import com.tencent.uikit.app.R -import com.tencent.uikit.app.main.BaseActivity -import com.trtc.tuikit.common.util.ToastUtil -import io.trtc.tuikit.atomicxcore.api.call.CallMediaType -import io.trtc.tuikit.atomicxcore.api.call.CallParams -import java.util.Arrays - -class GroupCallActivity : BaseActivity() { - private var editGroupId: EditText? = null - private var editUserList: EditText? = null - private var mediaType = CallMediaType.Audio - private var isOptionalParamViewExpand = false - - public override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.app_activity_group_call) - initView() - } - - private fun initView() { - editUserList = findViewById(R.id.et_user_id_list) - editGroupId = findViewById(R.id.et_group_id) - - findViewById(R.id.iv_back).setOnClickListener { onBackPressed() } - findViewById(R.id.btn_call).setOnClickListener { startGroupCall() } - findViewById(R.id.ll_setting).setOnClickListener { - startActivity(Intent(this, SettingsActivity::class.java)) - } - findViewById(R.id.rg_media_type).setOnCheckedChangeListener { group: RadioGroup?, checkedId: Int -> - mediaType = if (checkedId == R.id.rb_video) { - CallMediaType.Video - } else { - CallMediaType.Audio - } - } - val layoutChatGroupId: RelativeLayout = findViewById(R.id.rl_chat_group_id) - findViewById(R.id.ll_option).setOnClickListener { - layoutChatGroupId.visibility = if (!isOptionalParamViewExpand) View.VISIBLE else View.GONE - isOptionalParamViewExpand = !isOptionalParamViewExpand - } - } - - private fun startGroupCall() { - val userList = editUserList!!.getText().toString() - - if (TextUtils.isEmpty(userList)) { - AtomicToast.show( - this, - getString(R.string.app_please_input_user_id_list), - AtomicToast.Style.ERROR - ) - return - } - var userIdList: MutableList = mutableListOf() - if (userList.contains(",")) { - userIdList = - Arrays.asList(*userList.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) - } else if (userList.contains(",")) { - userIdList = - Arrays.asList(*userList.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) - } else { - userIdList = Arrays.asList(userList) - } - var callParams = createCallParams() - if (callParams == null) { - callParams = CallParams() - } - callParams.chatGroupId = editGroupId!!.getText().toString() - TUICallKit.createInstance(this).calls(userIdList, mediaType, callParams, null) - } - - private fun createCallParams(): CallParams? { - try { - if (SettingsConfig.callTimeOut !== 30 || !TextUtils.isEmpty(SettingsConfig.userData) || !TextUtils.isEmpty( - SettingsConfig.offlineParams - ) || SettingsConfig.intRoomId !== 0 || !TextUtils.isEmpty(SettingsConfig.strRoomId) - ) { - val callParams = CallParams() - callParams.timeout = SettingsConfig.callTimeOut - callParams.userData = SettingsConfig.userData - if (!TextUtils.isEmpty(SettingsConfig.strRoomId)) { - callParams.roomId = SettingsConfig.strRoomId - } - return callParams - } - } catch (e: Exception) { - } - return null - } -} \ No newline at end of file diff --git a/application/app/src/main/java/com/tencent/uikit/app/main/call/SettingDetailAcitivity.kt b/application/app/src/main/java/com/tencent/uikit/app/main/call/SettingDetailAcitivity.kt deleted file mode 100644 index 84030552..00000000 --- a/application/app/src/main/java/com/tencent/uikit/app/main/call/SettingDetailAcitivity.kt +++ /dev/null @@ -1,112 +0,0 @@ -package com.tencent.uikit.app.main.call - -import android.os.Bundle -import android.view.KeyEvent -import android.view.inputmethod.EditorInfo -import android.widget.Button -import android.widget.EditText -import android.widget.ImageView -import android.widget.TextView -import com.tencent.qcloud.tuicore.TUILogin -import com.tencent.qcloud.tuikit.tuicallkit.TUICallKit.Companion.createInstance -import com.tencent.uikit.app.R -import com.tencent.uikit.app.main.BaseActivity -import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast -import io.trtc.tuikit.atomicxcore.api.CompletionHandler - -class SettingDetailActivity : BaseActivity() { - private var editContent: EditText? = null - private var itemType = ITEM_USER_DATA - - public override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.app_activity_settings_detail) - initBundleData() - initView() - } - - private fun initBundleData() { - itemType = getIntent().getStringExtra(ITEM_KEY).toString() - } - - private fun initView() { - editContent = findViewById(R.id.et_content) - when (itemType) { - ITEM_USER_DATA -> { - editContent?.setText(SettingsConfig.userData) - editContent?.setHint(getString(R.string.app_invite_cmd_extra_info)) - } - - ITEM_OFFLINE_MESSAGE -> { - editContent?.setText(SettingsConfig.offlineParams) - editContent?.setHint(getString(R.string.app_offline_message_json_string)) - } - - ITEM_AVATAR -> { - editContent?.setText(TUILogin.getFaceUrl()) - editContent?.setHint(getString(R.string.app_avatar)) - } - - ITEM_RING_PATH -> { - editContent?.setText(SettingsConfig.ringPath) - editContent?.setHint(getString(R.string.app_set_ring_path)) - } - - else -> {} - } - findViewById(R.id.iv_back).setOnClickListener { finish() } - findViewById