From d93b15a35f073ba40f99ae54574252804735fe32 Mon Sep 17 00:00:00 2001 From: anonymous Date: Sat, 6 May 2023 17:28:05 +0800 Subject: [PATCH] update flutter uikit to 2.0.0 --- CHANGELOG.md | 155 +++ LICENSE | 220 +--- README.md | 745 ++++---------- doc/社交场景最佳实践.md | 509 --------- example/.metadata | 30 +- example/1400187352_3130303435333633/im.db | Bin 0 -> 4096 bytes example/1400187352_3130303435333633/im.db-shm | Bin 0 -> 32768 bytes example/1400187352_3130303435333633/im.db-wal | Bin 0 -> 3436112 bytes example/1400187352_3130303435333633/msg_0.db | Bin 0 -> 4096 bytes .../1400187352_3130303435333633/msg_0.db-shm | Bin 0 -> 32768 bytes .../1400187352_3130303435333633/msg_0.db-wal | Bin 0 -> 1194832 bytes example/imsdk_C.mmap2 | Bin 0 -> 153600 bytes example/imsdk_C_20221229.xlog | Bin 0 -> 211494 bytes example/imsdk_api_report | Bin 0 -> 273 bytes example/imsdk_config_1400187352 | Bin 0 -> 1237 bytes example/imsdk_sensitive_word_1400187352 | 2 + example/ios/Podfile | 2 +- example/ios/Podfile.lock | 216 ++-- example/lib/TIMUIKitChatExample.dart | 60 +- example/lib/TIMUIKitSearchExample.dart | 2 - example/lib/main.dart | 4 +- example/linux/.gitignore | 1 + example/linux/CMakeLists.txt | 138 +++ example/linux/flutter/CMakeLists.txt | 88 ++ .../flutter/generated_plugin_registrant.cc | 27 + .../flutter/generated_plugin_registrant.h | 15 + example/linux/flutter/generated_plugins.cmake | 27 + example/linux/main.cc | 6 + example/linux/my_application.cc | 104 ++ example/linux/my_application.h | 18 + example/macos/.gitignore | 7 + example/macos/Flutter/Flutter-Debug.xcconfig | 2 + .../macos/Flutter/Flutter-Release.xcconfig | 2 + .../Flutter/GeneratedPluginRegistrant.swift | 34 + example/macos/Podfile | 40 + example/macos/Podfile.lock | 68 ++ .../macos/Runner.xcodeproj/project.pbxproj | 632 ++++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 87 ++ .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + example/macos/Runner/AppDelegate.swift | 9 + .../AppIcon.appiconset/Contents.json | 68 ++ .../AppIcon.appiconset/app_icon_1024.png | Bin 0 -> 102994 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 0 -> 5680 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 0 -> 520 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 0 -> 14142 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 0 -> 1066 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 0 -> 36406 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 0 -> 2218 bytes example/macos/Runner/Base.lproj/MainMenu.xib | 343 +++++++ example/macos/Runner/Configs/AppInfo.xcconfig | 14 + example/macos/Runner/Configs/Debug.xcconfig | 2 + example/macos/Runner/Configs/Release.xcconfig | 2 + .../macos/Runner/Configs/Warnings.xcconfig | 13 + .../macos/Runner/DebugProfile.entitlements | 12 + example/macos/Runner/Info.plist | 32 + example/macos/Runner/MainFlutterWindow.swift | 15 + example/macos/Runner/Release.entitlements | 10 + example/pubspec.lock | 335 ++++-- example/pubspec.yaml | 11 +- .../flutter/generated_plugin_registrant.cc | 12 + .../windows/flutter/generated_plugins.cmake | 4 + images/folder_open.png | Bin 0 -> 440 bytes images/open_in_new.png | Bin 0 -> 374 bytes images/video_icon.png | Bin 0 -> 1502 bytes lib/base_widgets/tim_ui_kit_state.dart | 4 - .../separate_models/tui_chat_model_tools.dart | 40 +- .../tui_chat_separate_view_model.dart | 451 ++++---- .../tui_group_profile_model.dart | 8 +- .../tui_profile_view_model.dart | 18 +- .../view_models/tui_chat_global_model.dart | 148 +-- .../tui_conversation_view_model.dart | 45 +- .../view_models/tui_search_view_model.dart | 8 +- .../core/core_services_implements.dart | 9 +- lib/data_services/core/tim_uikit_config.dart | 30 +- .../tim_uikit_wide_modal_operation_key.dart | 43 + .../group/group_services_implement.dart | 1 + .../message/message_service_implement.dart | 5 +- lib/i18n/strings.i18n.json | 2 +- lib/i18n/strings_zh-Hans.i18n.json | 30 +- lib/i18n/strings_zh-Hant.i18n.json | 2 +- lib/tencent_cloud_chat_uikit.dart | 5 +- .../controller/tim_uikit_chat_controller.dart | 57 +- .../tim_uikit_conversation_controller.dart | 5 + .../tim_uikit_profile_controller.dart | 24 +- lib/ui/utils/common_utils.dart | 149 +++ lib/ui/utils/message.dart | 68 +- lib/ui/utils/permission.dart | 39 +- lib/ui/utils/platform.dart | 26 + lib/ui/utils/screen_shot.dart | 104 ++ lib/ui/utils/screen_utils.dart | 38 +- lib/ui/utils/sound_record.dart | 20 +- lib/ui/utils/time_ago.dart | 79 +- .../tim_uikit_add_friend.dart | 56 +- .../tim_uikit_send_application.dart | 66 +- .../TIMUIKitAddGroup/tim_uikit_add_group.dart | 53 +- .../tim_uikit_send_application.dart | 51 +- .../tim_uikit_black_list.dart | 77 +- ...ikit_chat_history_message_list_tongue.dart | 4 +- ...history_message_list_tongue_container.dart | 35 +- .../TIMUIKitTongue/tim_uikit_tongue_item.dart | 2 +- .../tim_uikit_chat_history_message_list.dart | 361 +++---- ..._uikit_chat_history_message_list_item.dart | 894 ++++++++++------ .../tim_uikit_chat_message_tooltip.dart | 461 ++++++--- ..._uikit_history_message_list_container.dart | 23 +- .../tim_uikit_message_read_receipt.dart | 60 +- .../TIMUIKitAppBar/tim_uikit_appbar.dart | 131 ++- .../tim_uikit_appbar_title.dart | 54 +- .../tim_uikit_message_reaction_detail.dart | 12 +- ...m_uikit_message_reaction_select_emoji.dart | 5 +- .../tim_uikit_message_reaction_show_item.dart | 12 +- .../tim_uikit_message_reaction_utils.dart | 8 +- .../tim_uikit_message_reaction_wrapper.dart | 11 +- .../tim_uikit_chat_face_elem.dart | 10 +- .../tim_uikit_chat_file_elem.dart | 71 +- .../tim_uikit_chat_file_icon.dart | 12 +- .../tim_uikit_chat_image_elem.dart | 174 ++-- .../tim_uikit_chat_reply_elem.dart | 155 +-- .../tim_uikit_chat_sound_elem.dart | 45 +- .../tim_uikit_chat_text_elem.dart | 45 +- .../tim_uikit_chat_text_translate_elem.dart | 224 ++-- .../tim_uikit_chat_video_elem.dart | 102 +- .../tim_uikit_merger_message_elem.dart | 59 +- .../TIMUIKitTextField/at_member_panel.dart | 136 +++ .../TIMUIKitTextField/tim_uikit_at_text.dart | 131 ++- .../tim_uikit_call_invite_list.dart | 32 +- .../tim_uikit_emoji_panel.dart | 1 + .../tim_uikit_more_panel.dart | 369 +++++-- .../tim_uikit_send_sound_message.dart | 2 +- .../tim_uikit_text_field.dart | 884 +++++++--------- .../tim_uikit_text_field_layout/narrow.dart | 611 +++++++++++ .../tim_uikit_text_field_layout/wide.dart | 963 ++++++++++++++++++ lib/ui/views/TIMUIKitChat/tim_uikit_chat.dart | 346 ++++--- .../TIMUIKitChat/tim_uikit_chat_config.dart | 55 +- .../tim_uikit_multi_select_panel.dart | 284 ++++-- .../TIMUIKitChat/tim_uikit_send_file.dart | 227 +++++ .../TIMUIKitContact/tim_uikit_contact.dart | 21 +- .../tim_uikit_conversation.dart | 376 ++++--- .../tim_uikit_conversation_draft_text.dart | 4 +- .../tim_uikit_conversation_item.dart | 24 +- .../tim_uikit_conversation_last_msg.dart | 18 +- .../views/TIMUIKitGroup/tim_uikit_group.dart | 89 +- .../tim_uikit_group_application_list.dart | 7 +- ...tim_uikit_group_application_list_item.dart | 4 - .../group_member/tui_add_group_member.dart | 104 +- .../group_member/tui_delete_group_member.dart | 105 +- .../group_member/tui_group_member_list.dart | 44 +- .../tim_uikit_group_profile.dart | 21 +- .../widgets/tim_ui_group_member_search.dart | 18 +- .../widgets/tim_ui_group_profile_widget.dart | 23 +- .../widgets/tim_ui_group_search_msg.dart | 3 +- .../widgets/tim_uikit_group_add_opt.dart | 108 +- .../widgets/tim_uikit_group_button_area.dart | 439 +++++--- .../widgets/tim_uikit_group_detail_card.dart | 302 +++--- .../widgets/tim_uikit_group_manage.dart | 956 ++++++++++------- .../widgets/tim_uikit_group_member_tile.dart | 264 +++-- .../tim_uikit_group_message_disturb.dart | 2 + .../widgets/tim_uikit_group_name_card.dart | 134 ++- .../widgets/tim_uikit_group_notification.dart | 188 +++- .../tim_uikit_group_pin_conversation.dart | 2 + .../widgets/tim_uikit_group_type.dart | 14 +- .../tim_uikit_new_contact.dart | 236 +++-- .../tim_uikit_unread_count.dart | 4 - .../TIMUIKitProfile/tim_uikit_profile.dart | 139 ++- .../widget/tim_uikit_operation_item.dart | 209 +++- .../tim_uikit_profile_userinfo_card.dart | 50 + ...m_uikit_profile_userinfo_card_narrow.dart} | 30 +- .../tim_uikit_profile_userinfo_card_wide.dart | 103 ++ .../widget/tim_uikit_profile_widget.dart | 261 +++-- .../pureUI/tim_uikit_search_input.dart | 54 +- .../pureUI/tim_uikit_search_item.dart | 106 +- .../pureUI/tim_uikit_search_showAll.dart | 8 +- .../TIMUIKitSearch/tim_uikit_search.dart | 116 ++- .../tim_uikit_search_item_wide.dart | 109 ++ .../TIMUIKitSearch/tim_uikit_search_msg.dart | 15 +- .../tim_uikit_search_msg_detail.dart | 99 +- lib/ui/widgets/avatar.dart | 25 +- lib/ui/widgets/az_list_view.dart | 49 +- lib/ui/widgets/column_menu.dart | 91 ++ lib/ui/widgets/contact_list.dart | 107 +- .../widgets/customize_ball_pulse_header.dart | 4 - lib/ui/widgets/drag_widget.dart | 97 ++ lib/ui/widgets/emoji.dart | 31 +- lib/ui/widgets/emoji.g.dart | 19 - lib/ui/widgets/forward_message_screen.dart | 61 +- lib/ui/widgets/group_member_list.dart | 67 +- lib/ui/widgets/link_preview/common/utils.dart | 20 +- .../link_preview/link_preview_entry.dart | 35 +- .../link_preview/widgets/link_text.dart | 11 + lib/ui/widgets/merger_message_screen.dart | 68 +- lib/ui/widgets/message_read_receipt.dart | 347 +++---- lib/ui/widgets/recent_conversation_list.dart | 26 +- lib/ui/widgets/textSize.dart | 5 +- lib/ui/widgets/text_input_bottom_sheet.dart | 281 ++++- .../widgets/transimit_group_owner_select.dart | 157 +-- lib/ui/widgets/video_screen.dart | 51 +- lib/ui/widgets/wide_popup.dart | 229 +++++ pubspec.lock | 521 ++++++---- pubspec.yaml | 42 +- screenshots/chat.jpg | Bin 50109 -> 0 bytes screenshots/chat.png | Bin 128456 -> 0 bytes screenshots/contact.jpg | Bin 48549 -> 0 bytes screenshots/conversation.jpg | Bin 55947 -> 0 bytes screenshots/group.jpg | Bin 57382 -> 0 bytes screenshots/profile.jpg | Bin 40582 -> 0 bytes 206 files changed, 13599 insertions(+), 6475 deletions(-) delete mode 100644 doc/社交场景最佳实践.md create mode 100644 example/1400187352_3130303435333633/im.db create mode 100644 example/1400187352_3130303435333633/im.db-shm create mode 100644 example/1400187352_3130303435333633/im.db-wal create mode 100644 example/1400187352_3130303435333633/msg_0.db create mode 100644 example/1400187352_3130303435333633/msg_0.db-shm create mode 100644 example/1400187352_3130303435333633/msg_0.db-wal create mode 100755 example/imsdk_C.mmap2 create mode 100644 example/imsdk_C_20221229.xlog create mode 100644 example/imsdk_api_report create mode 100644 example/imsdk_config_1400187352 create mode 100644 example/imsdk_sensitive_word_1400187352 create mode 100644 example/linux/.gitignore create mode 100644 example/linux/CMakeLists.txt create mode 100644 example/linux/flutter/CMakeLists.txt create mode 100644 example/linux/flutter/generated_plugin_registrant.cc create mode 100644 example/linux/flutter/generated_plugin_registrant.h create mode 100644 example/linux/flutter/generated_plugins.cmake create mode 100644 example/linux/main.cc create mode 100644 example/linux/my_application.cc create mode 100644 example/linux/my_application.h create mode 100644 example/macos/.gitignore create mode 100644 example/macos/Flutter/Flutter-Debug.xcconfig create mode 100644 example/macos/Flutter/Flutter-Release.xcconfig create mode 100644 example/macos/Flutter/GeneratedPluginRegistrant.swift create mode 100644 example/macos/Podfile create mode 100644 example/macos/Podfile.lock create mode 100644 example/macos/Runner.xcodeproj/project.pbxproj create mode 100644 example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 example/macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 example/macos/Runner/AppDelegate.swift create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png create mode 100644 example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png create mode 100644 example/macos/Runner/Base.lproj/MainMenu.xib create mode 100644 example/macos/Runner/Configs/AppInfo.xcconfig create mode 100644 example/macos/Runner/Configs/Debug.xcconfig create mode 100644 example/macos/Runner/Configs/Release.xcconfig create mode 100644 example/macos/Runner/Configs/Warnings.xcconfig create mode 100644 example/macos/Runner/DebugProfile.entitlements create mode 100644 example/macos/Runner/Info.plist create mode 100644 example/macos/Runner/MainFlutterWindow.swift create mode 100644 example/macos/Runner/Release.entitlements create mode 100644 images/folder_open.png create mode 100644 images/open_in_new.png create mode 100644 images/video_icon.png create mode 100644 lib/data_services/core/tim_uikit_wide_modal_operation_key.dart create mode 100644 lib/ui/utils/screen_shot.dart create mode 100644 lib/ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel.dart create mode 100644 lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart create mode 100644 lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart create mode 100644 lib/ui/views/TIMUIKitChat/tim_uikit_send_file.dart create mode 100644 lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart rename lib/ui/views/TIMUIKitProfile/widget/{tim_uikit_profile_userinfo_card.dart => tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_narrow.dart} (78%) create mode 100644 lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_wide.dart create mode 100644 lib/ui/views/TIMUIKitSearch/tim_uikit_search_item_wide.dart create mode 100644 lib/ui/widgets/column_menu.dart create mode 100644 lib/ui/widgets/drag_widget.dart delete mode 100644 lib/ui/widgets/emoji.g.dart create mode 100644 lib/ui/widgets/wide_popup.dart delete mode 100644 screenshots/chat.jpg delete mode 100644 screenshots/chat.png delete mode 100644 screenshots/contact.jpg delete mode 100644 screenshots/conversation.jpg delete mode 100644 screenshots/group.jpg delete mode 100644 screenshots/profile.jpg diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a6acde..86bae52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,158 @@ +## 2.0.0 + +If you are upgrading from version 1.7.0, please refer to the changelog of all 2.0.0-preview versions, ranging from preview.1 to preview.7. + +The main feature of this new 2.0.0 version is Desktop Support. Tencent Cloud Chat UIKit now supports all platforms, including iOS, Android, Web, Windows, and macOS, which has resulted in significant changes to the codebase. The UI has been improved to adapt to screens of various widths, with different layouts for both wide and narrow screens. + +In addition, there are some significant changes compared to version 2.0.0-preview.7. + +### New Features + +* Added drag and drop support for multiple files in `TIMUIKitChat`, allowing direct sending. +* Introduced functionality to open files or their containing folder (using `Finder` on `macOS` or `Explorer` on `Windows`) for file messages via the message operation tooltip menu on desktop. +* Implemented text selection and copying in messages on desktop. +* Added group joining application processing on Desktop. +* Introduced `isAutoReportRead` to `TIMUIKitChatConfig` for controlling read status reporting. + +### Improvements + +* Enhanced group members selection panel for mentioning someone in a group chat. +* Refined image display ratio on Desktop. +* The Reply or Quote button is now labeled as `Reply` when `isAtWhenReply` is set to true, and `Quote` otherwise. +* @ member tags can now be deleted at once. + +### Bug Fixes + +* Fixed UI layout issue causing the `translate` button to display on two lines. +* Addressed an issue causing the mute status not to change when switching to another conversation. +* Fixed several issues causing bugs when opening files. +* Resolved an issue causing secondary confirmation modal UI layout to be over-width on Desktop. +* Fixed an issue causing UI layout errors on the profile page. +* Addressed an issue where the `chatMessageItemFromSelfBgColor` configuration did not work. +* Fixed an issue preventing files from being opened when the path contained Chinese characters on Windows. +* Resolved an issue preventing images from being pasted and sent directly with Ctrl + V on Windows. +* Fixed an issue causing errors in the muting members list. + +## 2.0.0-preview.7 + +### New Features + +* Added `additionalMessageToolTips` to `ToolTipsConfig`. This new property allows developers to add additional message operation tooltip items, apart from the default ones. The previous `additionalItemBuilder` has been replaced by this new property. With `additionalMessageToolTips`, developers only need to specify the data for the tooltip items, rather than providing a whole widget. This makes usage easier, as you no longer need to worry about the UI display. +* Added `isPreloadMessagesAfterInit` to `TIMUIKitConfig`, allows determines whether TUIKit should preload some messages after initialization for faster message display. + +### Improvements + +* Message operation menu shows when long-pressing messages will not show if nothing operation item includes and do not use message sticker reaction module. +* Renamed `desktopMessageHoverBar` to `additionalDesktopMessageHoverBarItem` in `TIMUIKitChatConfig` to control only the addition of extra operation items displayed on the hover bar of messages on desktop (macOS, Windows, and desktop version of Web), without affecting the default ones. Previously, it controlled the entire message hover bar, including covering the default items. +* Renamed `showWideScreenModalFunc` to `showDesktopModalFunc` in `TIMUIKitConfig` for better clarity. +* Upgraded several dependencies to their latest versions, including `ffi` to ^2.0.1, `file_picker` to ^5.2.9 and `device_info_plus` to ^8.2.0. +* Added support for the new permission authorization schema on Android 13 and `targetSdkVersion` greater than 33. +* Corrected the `textHight` to `textHeight` in `TIMUIKitChatConfig`, and modified the default value to 1.3. + +### Bug Fixes + +* Fixed an issue where the `showVideoCall` and `showVoiceCall` configuration options were not working. +* Fixed potential `Windows` platform deployment prohibition issue. +* Fixed an issue that may cause `setLocalCustomData` to be triggered repeatedly. + +## 2.0.0-preview.6 + +### Improvements + +* Permission requests now feature a gray translucent overlay for secondary confirmations on first-time requests, which was reintroduced after being removed in version 2.0.0-preview.4. Additionally, the overlay can now be successfully hidden once the permission authorization is complete.". +* Time Divider on Message List: The default 12-hour display has been changed to a 24-hour display. +* Message translation now targets the language of TUIKit instead of relying on the system language directly. The language of TUIKit can be set as the system language automatically or defined by the user. For more information, please refer to this documentation: https://www.tencentcloud.com/document/product/1047/52154. +* Optimized the animation for message text input area. + +### Bug Fixes + +* Fixed an issue where the `Voice Call` and `Video Call` buttons were not working in group chat. +* Fixed several null-safety issues. +* Fixed a layout problem for the message operation menu when not using the message sticker reaction module. +* Addressed a problem where the time ago display was not correct on the conversation item. +* Fixed an issue where stickers could not be clicked in some cases. +* Resolved an overflow error that occurred when opening the sticker panel. + +## 2.0.0-preview.5 + +### New Features + +* New Chat Configuration: `isAllowLongPressAvatarToAt`. This option controls whether users are allowed to mention another user in the group by long-pressing on their avatar. + +### Improvements + +* Improved tool bar configuration on desktop: The tool bar can now be customized using `desktopControlBarConfig` for embedded default items and `additionalDesktopControlBarItems` for additional tool items. These configurations come from TIMUIKitChatConfig. +* Renamed the `wideMessageHoverBar` configuration option to `desktopMessageHoverBar` for better clarity. +* Eliminated the dependency on `fluttertoast`. All necessary customer reminders are now triggered through the `onTUIKitCallbackListener` info callback in your project. For more information, please see: https://www.tencentcloud.com/document/product/1047/50054#how-do-i-get-an-api-call-error.2Fflutter-layer-error.2Fpop-up-prompt-message.3F.3Ca-id.3D.22callback.22.3E.3C.2Fa.3E. +* Eliminated other six unnecessary dependency packages to reduce the size and improve performance. +* Improved the clarity of the `sendMessage` function in `TIMUIKitChatController` by replacing the use of `convID` to represent both `userID` and `groupID` with separate parameters. + +### Bug Fixes + +* Fixed an issue where the message operation menu may show inaccurately when the message is too long. +* Fixed a problem where the message operation menu had the potential to be too wide for certain types of messages, causing display issues. +* Corrected an issue where the button to remove group members was not functioning correctly. +* Addressed a problem where the message item could exceed the pixel limit and appear too wide. +* Fixed a bug where certain JSON decoding operations could potentially fail. +* Fixed an issue with sound messages on iOS devices playing only through earpiece instead of speaker by default. + +## 2.0.0-preview.4 + +### New Features + +* New Chat Configuration: `TIMUIKitChatConfig` now includes `offlinePushInfo`, which allows for customization of the entire `offlinePushInfo` for each message. This field has a higher priority than the previous separate configuration fields for this object. +* New Color Configuration: Added `appbarTextColor` and `appbarBgColor` to configure the color for the Appbar. Also added `selectPanelBgColor` and `selectPanelTextIconColor` to configure the color of the messages multi-select panel. + +### Improvements + +* Improved Group Management: Muting members on Work Group is now not allowed. +* Improved Avatar: Ensured that the avatar can be as small as possible while still covering the entire target box. +* Permission Requests: Removed the gray translucent overlay for secondary confirmations on first-time permission requests. + +### Bug Fixes + +* Fixed an issue where the color defined by `chatBgColor` could not cover the entire chat screen when messages did not cover the whole page. +* Fixed an issue where the history message list could not be scrolled in some cases. +* Fixed an issue where the ratio of sending messages was incorrect, resulting in the wrong position of the read status label on the left. +* Fixed an issue where loading messages could fail when the number of messages equaled the specified count. + +## 2.0.0-preview.3 + +### New Features + +* Integrated Callkit: The Calls button no longer needs to be added to `MorePanelConfig`. If `tencent_calls_uikit` is installed, the Video Call and Voice Call buttons will be displayed automatically. +* Paste Images on Desktop: Users can now paste an image on the text field on Desktop to send it. +* Screenshot Capture on Desktop: Users can now capture a screenshot on Desktop and send it. + +### Improvements + +* Improved Compatibility: The TUIKit is now compatible with Flutter versions 3.0.0 to 3.7.7. + +### Bug Fixes + +* Fixed an issue where the `businessID` type may not be correct. +* Fixed an issue where the `chatMessageItemFromSelfBgColor` configuration was not taking effect. + +## 2.0.0-preview.2 + +### New Features + +* Added support for opening files locally from file messages. + +## 2.0.0-preview.1 + +### New Features + +* Desktop Support: Tencent Cloud Chat UIKit now supports all platforms, including iOS, Android, Web, Windows, and macOS, resulting in significant changes to the codebase. The UI has been enhanced to adapt to screens of various widths, with different layouts for both wide and narrow screens. +* Information Copy: The ability to copy information, such as Group ID, from the screen has been added. + +### Improvements + +* Improved group management logic, with non-administrators no longer able to access the management interface. +* Optimized cursor positioning when sending messages. +* Improved and optimized scrollbar functionality. +* Enhanced clickable URL support in messages, with URLs now supporting both with and without the "https://" prefix. + ## 1.7.0+1 * Fix: An issue that caused errors on mentioning all members. diff --git a/LICENSE b/LICENSE index 3e1a561..8482e60 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,25 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Copyright © 2013-2023 Tencent Cloud. All Rights Reserved. - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: - 1. Definitions. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [2023] [Tencent] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md index 6708341..2a06226 100644 --- a/README.md +++ b/README.md @@ -63,123 +63,167 @@ More languages:
-![](https://qcloudimg.tencent-cloud.cn/raw/193ec650f17da6bb33edf5df5d978091.png) +![](https://qcloudimg.tencent-cloud.cn/image/document/8fd972397eba8f56c8f294c8b042794c.jpg)

TUIKit has Chat SDK, UI components and basic business logic inside. You can choose our pure Chat SDK tencent-cloud-chat-sdk if you tend to build the UI yourself.

- +
-## Experience DEMO +## Preview Version Release Notes -You can experience our Chat and Voice/Video Call modules via the following demos. +This version is a major update with version number 2.0.0-preview series, which is not backward +compatible. Tencent Cloud Chat UIKit has been extended from mobile-only (iOS/Android/mobile web) to +support all platforms, including iOS/Android/Web/Windows/macOS, resulting in significant changes to +the codebase. -**Those following versions of demo has been build by the same Flutter project with our SDKs and extensions.** +Therefore, users should evaluate the compatibility complexity of their business logic before +upgrading, while new users can use this version without any impact. -![](https://qcloudimg.tencent-cloud.cn/raw/89234f5032d4f6f8d89a8b439ca97ca2.png) +The documentation for the new version is still being improved, and users can refer to the sample app +source code at at https://github.com/TencentCloud/chat-demo-flutter. -**Also, taking a look of the screenshots of TUIKit from [here](https://www.tencentcloud.com/document/product/1047/50059?from=pub) are suggested.** +## Check Out Our Sample Apps + +Experience our Chat and Voice/Video Call modules by trying out our sample apps. + +**These apps have been created using the same Flutter project as our SDKs and extensions.** + +| Platform | Link | Remark | +|---------|---------|---------| +| Android / iOS | Tencent Chat Logo | Scan to download app for both Android and iOS. Automatically identifies platform. | +| Web | Tencent Chat Logo | Supports both desktop and mobile browsers and automatically adjusts its layout accordingly. Same website as link below. | +| Web | [Visit Now](https://comm.qq.com/flutter/#/) | Supports both desktop and mobile browsers and automatically adjusts its layout accordingly. Same website as previous QR code. | +| macOS | [Download Now](https://comm.qq.com/im_demo_download/macos_flutter.dmg) | The macOS version of our sample app. Control-click the app icon, then choose "Open" from the shortcut menu. | +| Windows | [Download Now](https://comm.qq.com/im_demo_download/windows_flutter.appx) | The Windows version of our sample app, which is a UWP (Universal Windows Platform) application. | +| Linux | Coming Soon... | Will be available later this year. | + +**Take a look at the screenshots of +TUIKit [here](https://www.tencentcloud.com/document/product/1047/50059?from=pub) to get an idea of +what to expect.** ## Introduction to TUIKit -[TUIKit](https://www.tencentcloud.com/document/product/1047/50059?from=pub) is a set of official UI components for Tencent Cloud Chat SDK, with chat business logic around it. It provides components such as the conversation, chat, relationship chain, and group. +Tencent Cloud Chat SDK comes +with [TUIKit](https://www.tencentcloud.com/document/product/1047/50059?from=pub), which is an +official set of UI components that have chat business logic built-in. TUIKit includes components +like conversation, chat, relationship chain, and group. -You can use these UI components to build your APP with the In-APP chat module quickly and easily. +Developers can use these UI components to quickly and easily add In-APP chat modules to their mobile +applications. ![img](https://qcloudimg.tencent-cloud.cn/raw/f140dd76be01a65abfb7e6ba2bf50ed5.png) -Currently, Flutter [TUIKit](https://www.tencentcloud.com/document/product/1047/50059?from=pub) contains the following main components: +Currently, Flutter [TUIKit](https://www.tencentcloud.com/document/product/1047/50059?from=pub) +contains the following main components: - [TIMUIKitCore](https://comm.qq.com/im/doc/flutter/en/TUIKit/TIMUIKitCore/readme.html): Core entry -- [TIMUIKitConversation](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitconversation): Conversation list -- [TIMUIKitChat](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitchat): Chat module, includes historical message list and message sending area, with some other features like message reaction and URL preview, etc. -- [TIMUIKitContact](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): Contacts list -- [TIMUIKitProfile](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitprofile): User profile and relationship management -- [TIMUIKitGroupProfile](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitgroupprofile): Group profile and management -- [TIMUIKitGroup](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): The list of group self joined -- [TIMUIKitBlackList](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): The list of user been blocked -- [TIMUIKitNewContact](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): New contacts application list -- [TIMUIKitSearch](https://www.tencentcloud.com/document/product/1047/50036?from=pub): Search globally -- [TIMUIKitSearchMsgDetail](https://www.tencentcloud.com/document/product/1047/50036?from=pub): Search in specific conversation +- [TIMUIKitConversation](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitconversation): + Conversation list +- [TIMUIKitChat](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitchat): + Chat module, includes historical message list and message sending area, with some other features + like message reaction and URL preview, etc. +- [TIMUIKitContact](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): + Contacts list +- [TIMUIKitProfile](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitprofile): + User profile and relationship management +- [TIMUIKitGroupProfile](https://www.tencentcloud.com/document/product/1047/50059?from=pub#timuikitgroupprofile): + Group profile and management +- [TIMUIKitGroup](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): + The list of group self joined +- [TIMUIKitBlackList](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): + The list of user been blocked +- [TIMUIKitNewContact](https://www.tencentcloud.com/document/product/1047/50059?from=pub#relationship-chain-components): + New contacts application list +- [TIMUIKitSearch](https://www.tencentcloud.com/document/product/1047/50036?from=pub): Search + globally +- [TIMUIKitSearchMsgDetail](https://www.tencentcloud.com/document/product/1047/50036?from=pub): + Search in specific conversation -Also, there are some other useful components and widgets, that can help to build your APP, and meet your business needs, including group entry application list and group member list, etc. +In addition to these components, there are other useful components and widgets available to help +developers meet their business needs, such as group entry application list and group member list. -For the source code of the project in the figure above, see [im-flutter-uikit](https://github.com/TencentCloud/tc-chat-demo-flutter). The project is open source and can be used directly. +For the source code of the project shown in the image above, please refer +to [chat-demo-flutter](https://github.com/TencentCloud/chat-demo-flutter). This project is open +source and can be directly used by developers. -## Supported Platforms +## Compatible Platforms + +The platforms are compatible with the deployment of our Chat UIKit. - Android - iOS -- Web(After version of 0.1.4) +- Web (version 0.1.4 and later) +- Windows (version 2.0.0 and later) +- macOS (version 2.0.0 and later) ## Get Started -**[Please refer this documents](https://www.tencentcloud.com/document/product/1047/45907?from=pub), for a completed and detailed get started guide.** +Please refer to [this document](https://www.tencentcloud.com/document/product/1047/45907?from=pub) for a complete and detailed guide on getting started. ## Directions -The following guide describes how to use Flutter TUIKit to build a simple Chat APP quickly. +The following guide describes how to quickly build a simple chat application using Flutter TUIKit. -**You may refer to the appendix, if willing to know about the detail and parameter for each widgets.** +Refer to the appendix if you want to learn about the details and parameters of each widget. -> If you tend to add this Flutter [TUIKit](https://www.tencentcloud.com/document/product/1047/50059?from=pub) to your existing application directly, you may refer to [this documentation](https://www.tencentcloud.com/document/product/1047/51456). Add the Flutter module to your existing app, coding once and deploying to all platforms. It could reduce your workload, to adding chat and call modules to your existing, to a large extent. +> If you want to directly add Flutter TUIKit to your existing application, refer to [this document](https://www.tencentcloud.com/document/product/1047/51456). You can add the Flutter module to your existing application, code once, and deploy to all platforms. This can significantly reduce the workload of adding chat and call modules to your existing application. -### Step 0. Create two accounts for testing +### Step 0: Create two accounts for testing -[Signed up](https://www.tencentcloud.com/document/product/378/17985?from=pub) and [log in](https://www.tencentcloud.com/document/product/378/36004?from=pub) to the [Tencent IM console](https://console.tencentcloud.com/im?from=pub). +Sign up and log in to the [Tencent Cloud Chat console](https://console.tencentcloud.com/im?from=pub). -[Create an application](https://www.tencentcloud.com/document/product/1047/34577?from=pub) and enter in. +Create an application and enter it. -Select [Auxiliary Tools](https://console.tencentcloud.com/im-detail/tool-usersig?from=pub) > UserSig Generation and Verification on the left sidebar. Generate two pairs of "UserID" and the corresponding "UserSig", and copy the "key" information. [Refer to here.](https://www.tencentcloud.com/document/product/1047/34580?from=pub#usersig-generation-and-verification) +Select Auxiliary Tools > UserSig Generation and Verification on the left sidebar. Generate two pairs of "UserID" and the corresponding "UserSig," and copy the "key" information. Refer to [this document](https://www.tencentcloud.com/document/product/1047/34580?from=pub#usersig-generation-and-verification). -Tips: You may create "user1" and "user2" here. +Tips: You can create "user1" and "user2" here. -> Note: +> Note: > -> The correct `UserSig` distribution method is to integrate the calculation code of `UserSig` into your server and provide an application-oriented API. When `UserSig` is needed, your application can send a request to the business server for a dynamic `UserSig`. For more information, see [How do I calculate UserSig on the server?](https://www.tencentcloud.com/document/product/1047/34385?from=pub). +> The correct way to distribute `UserSig` is to integrate the calculation code for `UserSig` into your server and provide an application-oriented API. When `UserSig` is needed, your application can send a request to the business server for a dynamic `UserSig.` For more information, see [How do I calculate UserSig on the server?](https://www.tencentcloud.com/document/product/1047/34385?from=pub). -### Step 1. Create a Flutter app and add permission configuration +### Step 1: Create a Flutter app and add permission configuration -Quickly create a Flutter APP by referring to [Flutter documentation](https://docs.flutter.dev/get-started/install). +Create a Flutter app quickly by following the [Flutter documentation](https://docs.flutter.dev/get-started/install). -TUIKit needs the permissions of shooting/album/recording/network for basic messaging function. You need to declare in the permission manually to use the relevant capabilities normally. +TUIKit needs the permissions of shooting/album/recording/network for basic messaging functions. You need to declare these permissions manually to use the relevant capabilities normally. #### Android -Open `android/app/src/main/AndroidManifest.xml`, add the following lines between `` and ``. +Open `android/app/src/main/AndroidManifest.xml` and add the following lines between `` and ``. ```xml - - - - - - - - - + + + + + + + + + + + ``` #### iOS -Open `ios/Podfile`, add the following lines to the end of the file. +Open `ios/Podfile` and add the following lines to the end of the file. ```pod post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) + target.build_configurations.each do |config| + config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64' + config.build_settings['ENABLE_BITCODE'] = 'NO' + config.build_settings["ONLY_ACTIVE_ARCH"] = "NO" + end target.build_configurations.each do |config| config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', @@ -192,7 +236,7 @@ post_install do |installer| end ``` -### Step 2. Install dependencies +### Step 2: Install dependencies Add `tencent_cloud_chat_uikit` under `dependencies` in the `pubspec.yaml` file, or run the following command: @@ -200,15 +244,15 @@ Add `tencent_cloud_chat_uikit` under `dependencies` in the `pubspec.yaml` file, flutter pub add tencent_cloud_chat_uikit ``` -It supports Android and iOS as default, if you are also willing to use it on the Web, please refer to the following guide. +It supports Android and iOS by default. If you also want to use it on the web, refer to the following guide. -#### Web Supports +#### Web Support -Version of 0.1.4 or later are required for web supports. +Version 0.1.4 or later is required to support web. -> If your existing Flutter project does not support Web, run `flutter create .` in the project root directory to add web support. +If your existing Flutter project does not support web, run `flutter create .` in the project root directory to add web support. -Install JS dependencies to `web/` by `npm` or `yarn`. +Install JavaScript dependencies to `web/` using `npm` or `yarn`. ```shell cd web @@ -220,7 +264,7 @@ npm i tim-js-sdk npm i tim-upload-plugin ``` -Open `web/index.html` , add the following two lines between `` and `` to import them. +Open `web/index.html` and add the following two lines between `` and `` to import them. ```html @@ -229,35 +273,35 @@ Open `web/index.html` , add the following two lines between `` and ` **You may also better to register a callback function for `onTUIKitCallbackListener` here, please refer to the appendix.** +> **You may also want to register a callback function for `onTUIKitCallbackListener` here. Refer to the appendix.** -### Step 4. Get the signature and log in +### Step 4: Get the signature and log in -Now, you can log in one of the testing accounts, generated on Step 0, to start the IM module. +You can now log in one of the testing accounts generated in Step 0 to start the Tencent Cloud Chat module. -Log in by `_coreInstance.login` . +Log in using `_coreInstance.login`. ```dart /// main.dart @@ -267,16 +311,16 @@ final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance(); _coreInstance.login(userID: userID, userSig: userSig); ``` -Caveat: Importing UserSig to your application is ONLY for Debugging purposes and cannot be applied for the Release version. Before publishing your app, you should generate your UserSig from your server. Refers to: +Note: Importing UserSig to your application is only for debugging purposes and cannot be used for the release version. Before publishing your app, you should generate your UserSig from your server. Refer to: -### Step 5. Implementing the conversation list page +## Step 5. Implementing the conversation list page -You can take the conversation (channel) list page as the homepage of your Chat module, covering the conversation with all users and groups that have chat records. +You can use the conversation (channel) list page as the homepage of your Chat module, which includes all conversations with users and groups that have chat records. - +```markdown +![Conversation List Page](https://qcloudimg.tencent-cloud.cn/raw/a27b131d555b1158d150bd9b337c1d9d.png) -You can create a `Conversation` class, with `TIMUIKitConversation` on its `body`, to render the conversation list. -The only parameter you need to provide at least is `onTapItem` callback, aimed at navigating to the Chat page for each conversation. The `Chat` class will be introduced in the next step. +You can create a `Conversation` class, with `TIMUIKitConversation` as its body, to render the conversation list. You only need to provide the `onTapItem` callback, which allows users to navigate to the Chat page for each conversation. In the next step, we'll introduce the `Chat` class. ```dart import 'package:flutter/material.dart'; @@ -284,6 +328,7 @@ import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; class Conversation extends StatelessWidget { const Conversation({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Scaffold( @@ -298,9 +343,10 @@ class Conversation extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (context) => Chat( - selectedConversation: selectedConv, - ), + builder: (context) => + Chat( + selectedConversation: selectedConv, + ), )); }, ), @@ -308,15 +354,14 @@ class Conversation extends StatelessWidget { } } ``` +## Step 6. Implementing the chat page -### Step 6. Implementing the chat page +The chat page consists of the main message list and a message sending bar at the bottom. -The chat page is composed of the main historical message list and a message sending bar at the bottom. +```markdown +![Chat Page](https://qcloudimg.tencent-cloud.cn/raw/09b8b9b54fd0caa47069544343eba461.jpg) -![](https://qcloudimg.tencent-cloud.cn/raw/09b8b9b54fd0caa47069544343eba461.jpg) - -You can create a `Chat` class, with `TIMUIKitChat` on its `body`, to render the chat page. -It is recommended to provide a `onTapAvatar` callback function, for navigating to the profile page for current contact, which will be introduced in the next step. +You can create a `Chat` class, with `TIMUIKitChat` as its body, to render the chat page. We recommend providing an `onTapAvatar` callback function to navigate to the profile page for the current contact, which we'll introduce in the next step. ```dart import 'package:flutter/material.dart'; @@ -324,42 +369,43 @@ import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; class Chat extends StatelessWidget { final V2TimConversation selectedConversation; + const Chat({Key? key, required this.selectedConversation}) : super(key: key); + String? _getConvID() { return selectedConversation.type == 1 ? selectedConversation.userID : selectedConversation.groupID; } + @override Widget build(BuildContext context) { return TIMUIKitChat( - conversationID: _getConvID() ?? '', // groupID or UserID - conversationType: selectedConversation.type ?? 1, // Conversation type - conversationShowName: selectedConversation.showName ?? "", // Conversation display name + conversationID: _getConvID() ?? '', + conversationType: selectedConversation.type ?? 1, + conversationShowName: selectedConversation.showName ?? "", onTapAvatar: (_) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => UserProfile(userID: userID), + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UserProfile(userID: userID), )); - }, // Callback for the clicking of the message sender profile photo. This callback can be used with `TIMUIKitProfile`. + }, ); -} + } ``` +## Step 7. Implementing the user profile page -### Step 7. Implementing the user profile page +This page shows the profile of a specific user and maintains the relationship between the current logged-in user and the other user. -This page can show the profile of a specific user and maintain the relationship between the current login user and it. +```markdown +![User Profile Page](https://qcloudimg.tencent-cloud.cn/raw/03e88da6f1d63f688d2a8ee446da43ff.png) -![](https://qcloudimg.tencent-cloud.cn/raw/03e88da6f1d63f688d2a8ee446da43ff.png) +You can create a `UserProfile` class, with `TIMUIKitProfile` as its body, to render the user profile page. -Here, you can create a `UserProfile` class, with `TIMUIKitProfile` on its `body`, to render the profile page. +The only parameter you have to provide is `userID`, while this component automatically generates the profile and relationship maintenance page based on the existence of friendship. -The only parameter you have to provide at least is 'userID', while this component can generate the profile and relationship maintenance page based on the existence of friendship automatically. - -> TIPS -> -> Please give priority to use `profileWidgetBuilder`, to customize some profile widgets, with `profileWidgetsOrder`, determine the vertical sequence, if you tend to customize this page. If this method could not meet your business needs, you may consider using `builder` instead. +> **TIP**: Please use `profileWidgetBuilder` first to customize some profile widgets and determine their vertical sequence using `profileWidgetsOrder` if you want to customize this page. If this method cannot meet your business needs, you may consider using `builder` instead. ```dart import 'package:flutter/material.dart'; @@ -367,34 +413,35 @@ import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; class UserProfile extends StatelessWidget { final String userID; + const UserProfile({required this.userID, Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text( - "Message", - style: TextStyle(color: Colors.black), - ), - ), - body: TIMUIKitProfile( - userID: widget.userID, - ), + title: const Text( + "Message", + style: TextStyle(color: Colors.black), + ), + ), + body: TIMUIKitProfile( + userID: widget.userID, + ), ); } } ``` -Now, your app can send/receive messages, show the conversation list, and deal with the contact friendship. - -You can use others components from TUIKit continually to implement the complete Chat module quickly and easily. +Now your app can send and receive messages, display the conversation list, and manage contact friendships. You can use other components from TUIKit to quickly and easily implement the complete Chat module. ## FAQs ### Do I need to integrate Chat SDK after integrating TUIKit? -No. You don't need to integrate Chat SDK again. If you want to use Chat SDK related APIs, you can get them via `TIMUIKitCore.getSDKInstance()`. This method is recommended to ensure Chat SDK version consistency. +No. You don't need to integrate Chat SDK again. If you want to use Chat SDK related APIs, you can +get them via `TIMUIKitCore.getSDKInstance()`. This method is recommended to ensure Chat SDK version +consistency. ### Why did force quit occur when I sent voice, image, file or other messages? @@ -404,11 +451,13 @@ Refers to Step 1 above. ### What should I do if clicking Build And Run for an Android device triggers an error, stating no available device is found? -Check that the device is not occupied by other resources. Alternatively, click Build to generate an APK package, drag it to the simulator, and run it. +Check that the device is not occupied by other resources. Alternatively, click Build to generate an +APK package, drag it to the simulator, and run it. ### What should I do if an error occurs during the first run for an iOS device? -If an error occurs after the configuration, click **Product > Clean Build Folder** , clean the product, and run `pod install` or `flutter run` again. +If an error occurs after the configuration, click **Product > Clean Build Folder** , clean the +product, and run `pod install` or `flutter run` again. ![](https://qcloudimg.tencent-cloud.cn/raw/d495b2e8be86dac4b430e8f46a15cef4.png) @@ -416,33 +465,33 @@ If an error occurs after the configuration, click **Product > Clean Build Folder ![](https://qcloudimg.tencent-cloud.cn/raw/1ffcfe39a18329c86849d7d3b34b9a0e.png) -Turn on Airplane Mode on your Apple Watch, and go to **Settings > Bluetooth** on your iPhone to turn off Bluetooth. +Turn on Airplane Mode on your Apple Watch, and go to **Settings > Bluetooth** on your iPhone to turn +off Bluetooth. Restart Xcode (if opened) and run `flutter run` again. -### Issue with Flutter environment? - -If you want to check the Flutter environment, run `flutter doctor` to detect whether the Flutter environment is ready. - ### What should I do when an error occurs on an Android device after TUIKit is imported into the application automatically generated by Flutter? ![](https://qcloudimg.tencent-cloud.cn/raw/d95efdd4ae50f13f38f4c383ca755ae7.png) -1. Open `android\app\src\main\AndroidManifest.xml` and complete `xmlns:tools="http://schemas.android.com/tools" / android:label="@string/android_label" / tools:replace="android:label"` as follows. +1. Open `android\app\src\main\AndroidManifest.xml` and + complete `xmlns:tools="http://schemas.android.com/tools" / android:label="@string/android_label" / tools:replace="android:label"` + as follows. ```xml + - + ``` -2. Open `android\app\build.gradle` and complete `minSdkVersion` and `targetSdkVersion` in `defaultConfig`. +2. Open `android\app\build.gradle` and complete `minSdkVersion` and `targetSdkVersion` + in `defaultConfig`. ```gradle defaultConfig { @@ -456,422 +505,8 @@ defaultConfig { ## Contact Us -Please do not hesitate to contact us in the following place, if you have any further questions or tend to learn more about the use cases. - -- Telegram Group: -- WhatsApp Group: -- QQ Group: 788910197, chat in Chinese - -Our Website: - ---- - -## Appendix: Overview for each widgets - -### TIMUIKitCore - -`TIMUIKitCore` provides two static methods, including `getInstance` and `getSDKInstance`。 - -- `getInstance`: Used for get the instance of `CoreServicesImpl`. -- `getSDKInstance`: Used for get the instance of Chat SDK. - -`CoreServicesImpl` is the main class of `TUIKit` , providing the methods includes initialization, logging in and out, getting user information, etc. - -```dart -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; - -final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance(); -final V2TIMManager _sdkInstance = TIMUIKitCore.getSDKInstance(); - -// init -_coreInstance.init( - language: LanguageEnum?, // Specify the displaying language among English / Chinese, Traditional / Chinese, Simplified. If this field is not provided, the default is the system language - onTUIKitCallbackListener: ValueChanged, // The callback listener for information from TUIKit, includes errors from SDK API/ the info needs to reminds users/ errors from Flutter. You can reminds users up to your business needs, the description below for details. - sdkAppID: 0, // sdkAppID from Tencent IM console - loglevel: LogLevelEnum.V2TIM_LOG_DEBUG, - listener: V2TimSDKListener()); -// unInit -_coreInstance.unInit(); - -// login -_coreInstance.login( - userID: 0, // user ID - userSig: "" // [How do I calculate UserSig on the server?](https://www.tencentcloud.com/document/product/1047/34385?from=pub) -) - -// logout -_coreInstance.logout(); - -// getUsersInfo -_coreInstance.getUsersInfo(userIDList: ["123", "456"]); - -// setOfflinePushConfig -_coreInstance.setOfflinePushConfig( - businessID: businessID, // The business from Tencent IM console, for each platform of devices - token: token, // The token from manufactors when registering the offline push -) - -// setSelfInfo -_coreInstance.setSelfInfo(userFullInfo: userFullInfo) // set self userinfo - -// setTheme -_coreInstance.setTheme(TUITheme theme: theme) // set theme color -/* - TUITheme( - // Primary color - final Color? primaryColor; - - // Secondary color - final Color? secondaryColor; - - // Info color, for secondary operations or prompts - final Color? infoColor; - - // Weak background color, lighter than the main background color, used to fill gaps or shadows - final Color? weakBackgroundColor; - - // Weak divider line color, for dividing lines or borders - final Color? weakDividerColor; - - // Weak text color - final Color? weakTextColor; - - // Dark text color - final Color? darkTextColor; - - // Used for AppBar or Panels - final Color? lightPrimaryColor; - - // Text color - final Color? textColor; - - // Warning color for dangerous operation - final Color? cautionColor; - - // Group owner identification color - final Color? ownerColor; - - // Group administrator identification color - final Color? adminColor;) -*/ -``` - -#### `onTUIKitCallbackListener` - -This listener is used to get information including: errors form SDK API / errors form Flutter / some remind information that may need to pop up to prompt users. - -Determine the type by `TIMCallbackType`. - -> You may refer to our [DEMO](https://github.com/TencentCloud/tc-chat-demo-flutter/lib/src/pages/app.dart) for the codes in this part, and modifying up to your business needs. - -##### Errors form SDK API(`TIMCallbackType.API_ERROR`) - -In this scenario, SDK API original `errorMsg` and `errorCode` are provided. - -[Error codes listed here](https://www.tencentcloud.com/document/product/1047/34348?from=pub) - -#### Errors form Flutter(`TIMCallbackType.FLUTTER_ERROR`) - -This error is captured by listening Flutter natively throwing an exception, providing `stackTrace` (from `FlutterError.onError`) or `catchError` (from try-catch) when the error occurs. - -#### Remind information(`TIMCallbackType.INFO`) - -It is suggest to pup up to prompt users for this kind of messages. - -Provide the `infoCode` info code to help you determine the current scene, and provide the default prompt recommendation `infoRecommendText`. - -You can directly pop up our recommendations, or you can customize the recommendations according to the scene code. The language of recommendation text is adaptive according to the system language or the language you specified, do not judge the scene according to the recommendation language. - -The rules for info code are as follows: - -The info code consists of seven digits, the first five digits determine the components of the scene, and the last two digits determine the specific performance of the scene. - -| The first five digits | Corresponding widget | -| ---------- | ---------------------- | -| 66601 | `TIMUIKitAddFriend` | -| 66602 | `TIMUIKitAddGroup` | -| 66603 | `TIMUIKitBlackList` | -| 66604 | `TIMUIKitChat` | -| 66605 | `TIMUIKitContact` | -| 66606 | `TIMUIKitConversation` | -| 66607 | `TIMUIKitGroup` | -| 66608 | `TIMUIKitGroupProfile` | -| 66609 | `TIMUIKitNewContact` | -| 66610 | `TIMUIKitGroupProfile` | -| 66611 | `TIMUIKitNewContact` | -| 66612 | `TIMUIKitProfile` | -| 66613 | `TIMUIKitSearch` | -| 66614 | General Widget | - -All info codes are listed below: - -| `infoCode` | Recommendation prompt `infoRecommendText` | Scene description | -| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -| 6660101 | Contact request sent | User requests to add another user as a contact. | -| 6660102 | This user is your contact. | When a user applies to add another user who is already a contact, the callback of `onTapAlreadyFriendsItem` is triggered. | -| 6660201 | Group request sent | Users apply to join a group chat that requires the approval of the administrator.| -| 6660202 | You are already in this group | When a user applies to join a group, it is determined that the user is already a member of the current group, triggering the callback of `onTapExistGroup`. | -| 6660401 | Failed to locate the original message | When the user needs to jump to the @ message or reference the message, the target message is not found in the message list. | -| 6660402 | Video saved successfully | After clicking on the video message in the message list, and chooses to save the video. | -| 6660403 | Failed to save the video | After clicking on the video message in the message list, and chooses to save the video. | -| 6660404 | Message too short | The user sent an overly short voice message. | -| 6660405 | Sending failed. The video cannot exceed 100 MB. | The user attempted to send a video larger than 100MB. | -| 6660406 | Image saved successfully | After clicking on the image in the message list, the user chooses to save the picture. | -| 6660407 | Failed to save the image | After clicking on the image in the message list, the user chooses to save the picture. | -| 6660408 | Copied | The user chooses to copy the text message in the pop-up window. | -| 6660409 | Not implemented | The user selects a non-implemented function in the pop-up. window | -| 6660410 | You are receiving other files | When the user clicks the download file message, the previous download task has not yet been completed. | -| 6660411 | Receiving | User clicks to download file message. | -| 6660412 | Video is available with .mp4 only | The user sent a video message in non-mp4 format | -| 6660413 | Added to download queue and waiting | Added to the queue to be downloaded, while other files are downloading | -| 6661001 | Modification failed due to network disconnection | When users try to modify group data in a non-network environment. | -| 6661002 | Failed to view the group members due to network disconnection | When users try to modify group data in a non-network environment. | -| 6661003 | Admin role canceled successfully | The user removes the other users from the administrator in the group. | -| 6661201 | Modification failed due to network disconnection | When a user tries to modify his or her contact information without a network environment. | -| 6661202 | Added successfully | Add other users as contact on the profile page and automatically add them successfully without verification. | -| 6661203 | Request sent successfully | Add other users as contact on the profile page, and the other user's settings need to be verified. | -| 6661204 | The user is blocked | Add other users as contacts on the profile page, who are on their own blocklist. | -| 6661205 | Added failed | Add other users as contact on the profile page, but failed, probably because the other party is forbidden to add contact. | -| 6661206 | Deleted successfully | Delete other users as contact on the profile page and succeed. | -| 6661207 | Deleted failed | Delete other users as contact on the profile page. Failed. | -| 6661401 | The input cannot be empty | When the user is entering information, an empty string is entered. | -| 6661402 | Please provide a life cycle hook navigating back to home or other pages. | When users quit the group or dissolve the group, they did not provide a way to return to the home page. | -| 6661403 | Insufficient disk storage space, it is recommended to clean up to obtain a better experience | After the login is successful, the device storage space will be automatically detected. If there is less than 1GB, it will be prompted. | - -### TIMUIKitConversation - -`TIMUIKitConversation` shows the conversation list. - -The corresponding controller: `TIMUIKitConversationController` is also provided. - -```dart -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; - -final TIMUIKitConversationController _controller = - TIMUIKitConversationController(); - -void _handleOnConvItemTaped(V2TimConversation? selectedConv) { - // You can jump to the chat interface here. -} - -List _itemSlidableBuilder( - V2TimConversation conversationItem) { - return [ - ConversationItemSlidablePanel( - onPressed: (context) { - _clearHistory(conversationItem); - }, - backgroundColor: hexToColor("006EFF"), - foregroundColor: Colors.white, - label: 'Clear conversaation', - autoClose: true, - ), - ConversationItemSlidablePanel( - onPressed: (context) { - _pinConversation(conversationItem); - }, - backgroundColor: hexToColor("FF9C19"), - foregroundColor: Colors.white, - label: conversationItem.isPinned! ? 'unpined' : 'pinned', - ) - ]; - } - -TIMUIKitConversation( - lifeCycle: ConversationLifeCycle(), // The lifecycle hook - onTapItem: _handleOnConvItemTaped, // Callback of clicking conversation, can navigating to chat page - itemSlidableBuilder: _itemSlidableBuilder, // Operation items for conversation Item sliding to the left, conversation topping, etc. - controller: _controller, // Conversation component controller, through which you can get conversation data, set conversation data, pin conversation to top and other operations - itembuilder: (conversationItem) {} // Used to customize the conversation item. Can be combined with TIMUIKitConversationController to implement business logic. - conversationCollector: (conversation) {} // Conversation collector, which can customize whether the conversation is displayed - lastMessageBuilder: (V2TimMessage, List) {} // Customize the second line of the conversation item, which is generally used to show the last message -) -``` - ---- - -### TIMUIKitChat - -`TIMUIKitChat` is the main chat component that provides the display of message list and the ability to send messages. - -It also supports custom display of various message types. - -Additionally, it can be combined with `TIMUIKitChatController` to realize local storage and pre-rendering of messages, etc. - -Currently supported message parsing: - -- Text message. -- Image message. -- Video message. -- Voice message. -- Group message. -- Merge message. -- File message. - -```dart -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; - -TIMUIKitChat( - lifeCycle: ChatLifeCycle(), // Lifecycle hook for TIMUIKitChat - conversationID: "", // User ID or Group ID - conversationType: ConversationType, // 1 is c2c chat, 2 is group chat - conversationShowName: "", - appBarActions: [], // appBar operation item, which can be used to jump to the page of group details and personal details, etc. - onTapAvatar: _onTapAvatar, // callback function for clicking the avatar, which can be used to jump to the user profile. - messageItemBuilder: (MessageItemBuilder) { - // Message item layout constructor, you can choose to customize part of the message type or message row layout. - }, - extraTipsActionItemBuilder: (message) { - // The configuration for the menu, opend by long pressed messages - }, - morePanelConfig: MorePanelConfig(), // The config for more panel area - appBarConfig: AppBar(), // The config for AppBar - mainHistoryListConfig: ListView(), // Additional config for ListView of historical message list - textFieldHintText: "", // The hint of inputTextField - draftText: "", // The draft of inputting message - initFindingMsg: 0, // The message been jumped - config: TIMUIKitChatConfig(), // The config for the whole TIMUIKitChat - onDealWithGroupApplication: (String groupID){ - // Navigating to the pages for the page of [TIMUIKitGroupApplicationList] or other pages to handle joining group application for specific group - } -) -``` - ---- - -### TIMUIKitProfile - -`TIMUIKitProfile` shows the detail information for a user, and manage the relationship. - -```dart -TIMUIKitProfile( - userID: "", - controller: TIMUIKitProfileController(), // Profile Controller - profileWidgetBuilder: ProfileWidgetBuilder(), // Customized some kinds of item. - profileWidgetsOrder: List, // Determine the vertical sequence for those profile widgets. - builder: ( - BuildContext context, - V2TimFriendInfo friendInfo, - V2TimConversation conversation, - int friendType, - bool isMute) { - // Customized the whole page. `profileWidgetBuilder` and `profileWidgetsOrder` will no longer works if you define this. - }, - lifeCycle: ProfileLifeCycle(),// Lifecycle hook for TIMUIKitProfile -) -``` - ---- - -### TIMUIKitGroupProfile - -`TIMUIKitGroupProfile` shows the details of a group and can manage this group. - -```dart -TIMUIKitGroupProfile( - groupID: "", - profileWidgetBuilder: GroupProfileWidgetBuilder(), // Customized some kinds of item. - profileWidgetsOrder: List, // Determine the vertical sequence for those profile widgets. - builder: (BuildContext context, V2TimGroupInfo groupInfo, List groupMemberList){ - // Customized the whole page. `profileWidgetBuilder` and `profileWidgetsOrder` will no longer works if you define this. - }, - lifeCycle: GroupProfileLifeCycle, // Lifecycle hook for TIMUIKitGroupProfile -) -``` - ---- - -### TIMUIKitBlackList - -`TIMUIKitBlackList` shows the list of blocked users. - -```dart -TIMUIKitBlackList( - onTapItem: (_) {}, // Callback of clicking the item - emptyBuilder: () {} // The builder when no user listed - itemBuilder: () {} // Customized the user item - lifeCycle: BlockListLifeCycle(), // Lifecycle hook for TIMUIKitBlackList -) -``` - ---- - -### TIMUIKitGroup - -`TIMUIKitGroup` shows the list of joined group. - -```dart -TIMUIKitGroup( - onTapItem: (_) {}, // Callback of clicking the item - emptyBuilder: () {} // The builder when no group listed - itemBuilder: () {} // Customized the group item -) -``` - ---- - -### TIMUIKitContact - -`TIMUIKitContact` shows the list of contacts. - -```dart -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; - -TIMUIKitContact( - lifeCycle: FriendListLifeCycle(), // Lifecycle hook for TIMUIKitContact - topList: [ - TopListItem(name: "New Contact", id: "newContact"), - TopListItem(name: "Group", id: "groupList"), - TopListItem(name: "Blocklist", id: "blackList") - ], // Top list array - topListItemBuilder: _topListBuilder, // The builder for top list array - onTapItem: (item) { }, // Callback of clicking a contact - emptyBuilder: (context) => const Center( - child: Text("No cantact"), - ), // The builder when no contact listed - ); -``` - -### TIMUIKitSearch - -`TIMUIKitSearch` is a global search widget. Global search supports search for "contacts" / "groups" / "chat records". -`TIMUIKitSearchMsgDetail` is an intra-conversation search component that can search for chat records for a specific conversation. - -```dart -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; - -// Search globally -TIMUIKitSearch( - onTapConversation: _handleOnConvItemTapedWithPlace, // Function(V2TimConversation, V2TimMessage? message), navigating to specific message from specific conversation - onEnterConversation: (V2TimConversation conversation, String initKeyword){}, // Navigating to search in specific conversation. Please navigate to TIMUIKitSearchMsgDetail manually -); - -// Search inside a specific conversation -TIMUIKitSearchMsgDetail( - currentConversation: conversation!, - onTapConversation: onTapConversation, - keyword: initKeyword ?? "", - ); -``` - -## What's more - -In addition to Flutter SDK, we have numerous SDKs that covering all platforms. The following platforms can communicate with each other and provide services across devices and platforms. - -| Platform | Introduction | Demo | Download | UI Components library | -| --- | --- | --- | --- | --- | -| Android | Compatible with JDK 1.6 and Android SDK version 14 and later | [Get](https://www.tencentcloud.com/document/product/1047/34279) | [Get](https://github.com/TencentCloud/TIMSDK/tree/master/Android/IMSDK) | [Get](https://www.tencentcloud.com/document/product/1047/50062) | -| iOS | Compatible with iOS 8.0 and later | [Get](https://www.tencentcloud.com/document/product/1047/34279) | [Get](https://github.com/TencentCloud/TIMSDK/tree/master/iOS/IMSDK) | [Get](https://www.tencentcloud.com/document/product/1047/50062) | -| Mac | Compatible with OS X 10.10 and later | - | [Get](https://github.com/TencentCloud/TIMSDK/tree/master/Mac/IMSDK) | - | -| Windows | C and C++ are included. Compatible with Windows 7, Windows 8 and 8.1, and Windows 10. Both 32-bit and 64-bit programs can be connected | - | [Get](https://github.com/TencentCloud/TIMSDK/tree/master/Windows/IMSDK) | - | -| Web | Supports Internet Explorer 11+, Chrome 7+, Firefox 3.6+, Opera 12+ and Safari 6+ | [Get](https://www.tencentcloud.com/document/product/1047/34279) | [Get](https://www.npmjs.com/package/tim-js-sdk) | [Get](https://www.tencentcloud.com/document/product/1047/50061) | -| Unity | Supports 2020.2.7f1c1 or later | - | [Get](https://www.tencentcloud.com/document/product/1047/46263) | - | -| Flutter | Supports Flutter 2 & dart 2.12 and later, deploying to Android, iOS, Web, macOS and Windows. | [Get](https://www.tencentcloud.com/document/product/1047/34279) | Here | [Get](https://pub.dev/packages/tencent_cloud_chat_uikit) | -| Electron | Electron SDK | - | [Get](https://github.com/tencentyun/im_electron_demo) | - | - -## Contact Us - -Please do not hesitate to contact us in the following place, if you have any further questions or tend to learn more about the use cases. +Please do not hesitate to contact us in the following place, if you have any further questions or +tend to learn more about the use cases. - Telegram Group: - WhatsApp Group: diff --git a/doc/社交场景最佳实践.md b/doc/社交场景最佳实践.md deleted file mode 100644 index 118f1d6..0000000 --- a/doc/社交场景最佳实践.md +++ /dev/null @@ -1,509 +0,0 @@ - -# 社交场景最佳实践方案 - -社交模块是目前主流应用程序最常见的功能之一。有了社交模块,用户在您的应用内,可以自由的交流互动,并添加好友,关注其他用户等等。 - -这可在很大程度上,促进您应用程序的活跃度,吸引用户留存,获取更多新用户,并可拓展您应用的业务范围。让更多用户花更多时间在您的应用程序上。 - -例如, - -- 交友软件,其核心便是社交聊天模块,用于匹配对话及用户关系链维护,让更多的用户相聚与相识; -- 音乐软件,可用社交模块让乐迷及粉丝群体实时沟通,打造音乐社区文化; -- 教育软件,可用社交模块打通 "学校-教师-家长" 循环,促进家校互动,形成家校社三合力,更大程度发挥教育影响作用,保证教育的一致性与连贯性; -- 电子游戏,特别是RPG类型,内置的聊天模块让玩家能在线组局,一起作战,并组建工会,创造游戏内社区,提升游戏社交属性,丰富体验,提升活跃度; -- 医疗软件,聊天及社群模块让患者间得以互助交流,一起战胜病魔,走出病情,让大家看到希望; -- 导航软件,堵车交流群,让归心似箭的旅行者们,交流前方最新情报,不再无聊干等,发发段子调侃一下,为拥堵的出行,带来一些希望与欢乐。 - -因此,社交聊天模块可谓是您应用程序不可或缺的能力。 - -本文将以腾讯云IM为基础,梳理现有应用在接入社交场景过程中常见需求,给出解决实现方案。以及可能遇到的问题、需要注意的细节点等,希望能帮助客户朋友们快速的理解业务、实现需求。 - ->? 本文档主要介绍社交场景的通用SDK实现方案,文中示例截图来自于我们的[Flutter TUIKit](https://cloud.tencent.com/document/product/269/70747),您可根据需要,选用我们提供的全部平台SDK或TUIKit。 - -## 用户 - -腾讯云IM支持托管维护用户信息与用户资料。您可直接将您应用的用户资料存储与我们的服务内,并通过相关API进行读取/更新/维护操作。 - -对于社交场景,常见用户资料可分为基本信息资料和其他信息资料。 - -|基本信息|其他信息| -|---|---| -|用户名,性别,生日,所在地,个性签名,昵称等|其他社交模块内需要的资料| - -### 导入现有用户数据 - -如果您需要给您现有应用,添加社交能力。可直接使用我们的服务端API,快速将您现有用户数据,完整导入至腾讯云IM中。 - -导入完成后,现有用户可直接使用其原有身份数据,和其他用户发起会话,一起聊天,开启社交之旅。 - -[导入多个账号 - 服务端API](https://cloud.tencent.com/document/product/269/4919) - -### 用户在线状态 - -腾讯云IM支持自动上报并让其他用户获取[在线状态信息](https://cloud.tencent.com/document/product/269/3665)。 - -状态包括:前台运行状态 / 后台运行状态 / 未登录状态。 - -利用这一能力,您可让用户看到其他用户的在线状态,增强互动性。 - -此外,您还可使用这一能力,针对您的业务场景,做许多功能拓展。例如,交友软件,能够优先推荐匹配在线的用户,让聊天可进行的更顺畅,缘分更快相聚。 - -| 会话列表用户在线状态 | 通讯录用户在线状态 | -|---------|---------| -| | | - -#### 获取用户在线状态 - -在客户端上, 您可调用 [`getUserStatus`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMManager/getUserStatus.html) 方法,[批量查询其他用户的在线状态](https://cloud.tencent.com/document/product/269/75511#.E6.9F.A5.E8.AF.A2.E7.94.A8.E6.88.B7.E7.8A.B6.E6.80.81)。 - -此外,在服务端上,也可[通过REST API,获取用户状态](https://cloud.tencent.com/document/product/269/2566)。 - -#### 订阅用户在线状态变更 - -其他用户的在线状态总是实时在变化的,您可在客户端上,调用 [`subscribeUserStatus`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMManager/subscribeUserStatus.html) 方法,[批量订阅其他用户的在线状态](https://cloud.tencent.com/document/product/269/75511#.E8.AE.A2.E9.98.85.E7.94.A8.E6.88.B7.E7.8A.B6.E6.80.81)。当发生变化时,将通过回调函数通知您,您可根据其,修改界面UI并完成其他您的业务操作。 - -## 好友 - -好友管理,又称关系链管理,是社交场景的基础。众多会话/聊天特性,都要依赖于好友关系状态。有了好友关系链能力,众多的用户才能得以串联起来,互动形成整体。 - -例如微信/QQ只允许好友间发起一对一单聊;交友软件则常常可在非好友的情况下,进行有限度的聊天;在线娱乐社区软件,则常常不需要好友关系即可会话。 - -因此,您需要根据您的应用使用场景,确定好友及关系链管理的用法。 - -| 通讯录 | -|---------| -| | - -### 好友关系 - -腾讯云IM支持单个用户添加最多3000个好友。 - -#### 好友关系类型 - -好友关系类别包含单向好友和双向好友。 - -- 双向好友:用户 A 的好友表中有用户 B,B 的好友表中也有 A。 -- 单向好友:用户 A 的好友表中有用户 B,但 B 的好友表中却没有 A。 - -#### 添加好友验证方式 - -一回合加好友:如果帐号 A 设置的加好友验证方式是 [AllowType_Type_AllowAny](https://cloud.tencent.com/document/product/269/1500#.E6.A0.87.E9.85.8D.E8.B5.84.E6.96.99.E5.AD.97.E6.AE.B5),那么任何人添加 A 为好友都可直接添加成功,这种一个请求就添加好友成功的场景称作一回合加好友。 - -两回合加好友:如果帐号 A 设置的加好友验证方式是 [AllowType_Type_NeedConfirm](https://cloud.tencent.com/document/product/269/1500#.E6.A0.87.E9.85.8D.E8.B5.84.E6.96.99.E5.AD.97.E6.AE.B5),那么任何人添加 A,A 都会收到一个请求加好友验证消息,这是第一个回合,然后 A 对这个请求加好友验证消息进行同意操作时,这是第二个回合,这种需要验证的加好友场景就被称为两回合加好友。 - -### 非好友发消息 - -对于某些场景,需要非好友关系也能发送消息。例如对于交友软件,常常允许匹配到的陌生人,发送若干条消息打招呼。 - -这需要您在[腾讯云IM的控制台](https://console.cloud.tencent.com/im/login-message),关闭 “好友关系检查” 功能。 - -![](https://qcloudimg.tencent-cloud.cn/raw/a7d79a4f4af1301879683f1ff99dcdd8.png) - -如果您需要针对陌生人发消息的数量加以限制,可在您的业务层实现。发送若干条消息后,不再允许发送即可。 - -## 群组 - -有的时候,仅一对一单聊无法满足您的社交场景要求。 - -例如对于音乐类型app,优质的乐迷群及粉丝群,有助于打造音乐社区文化,吸引用户留存。 - -### 群组类型 - -腾讯云IM支持多种类型的群,为便于理解,在这里以常见的群聊举例。 - -#### 微信群 - 好友工作群 Work - -Work群,类似普通微信群。创建后仅支持已在群内的好友邀请加群,且无需被邀请方同意或群主审批。 - -该群适合用于打造好友间互动拉入,产生的群。 - -#### QQ群 - 陌生人社交群 Public - -Public群,类似QQ群。创建后群主可指定群管理员,用户搜索群 ID 发起加群申请后,需要群主或管理员审批通过(可选)才能入群。 - -该群适合用于打造兴趣社区,用户在您的app中,发现好玩的兴趣群组,可按需主动加入。 - -#### 会议群 - Meeting - -创建后可随意进出,且支持查看入群前消息。 - -适合用于音视频会议场景、在线教育场景等与实时音视频产品结合的场景。 - -#### 直播群 - AVChatRoom - -创建后可随意进出,没有群成员数量上限,但不支持历史消息存储。 - -适合与直播产品结合,用于弹幕聊天场景。 - -#### Discord - 社群 Community - -创建后可随意进出,最多支持10w人,支持历史消息存储,用户搜索群 ID 发起加群申请后,无需管理员审批即可进群。[详情可查看此文档](https://cloud.tencent.com/document/product/269/83870)。 - -### 群资料 - -群资料主要包括 群组本身的资料 和 群成员资料。 - -#### 群组本身的资料 - -群组资料是指单个群组维度的属性,包括群名称、简介、公告、群主等,以及群组维度自定义字段。 - -##### 获取群资料 - -在客户端上,可调用 [`getGroupsInfo`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMGroupManager/getGroupsInfo.html) 方法,获取特定群组资料详情。 - -##### 修改群资料 - -可修改群组名称、群组简介、群组公告、群组头像、群名片,修改加群选项、群纬度自定义字段、用户群内身份、群成员维度自定义字段和接收群消息选项等信息。 - -在客户端上,可调用 [`setGroupInfo`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMGroupManager/setGroupInfo.html) 方法,修改特定群组资料详情。 - -#### 群成员资料 - -群成员资料主要包括,特定成员,在群内的备注名/角色/禁言状态/自定义字段信息。在强社交场景的群内,会非常实用。 - -##### 获取群成员资料 - -可通过客户端 [`getGroupMembersInfo`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMGroupManager/getGroupMembersInfo.html) 方法或 [`getGroupMemberList`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMGroupManager/getGroupMemberList.html) 方法获取此信息。 - -##### 修改群成员资料 - -不同的群成员资料,调用不同的API方法修改。[详情可查看此处](https://cloud.tencent.com/document/product/269/37411#.E7.BE.A4.E6.88.90.E5.91.98)。 - -## 会话 - -一个会话,您可理解为同某个特定用户的单聊,或一个群聊的消息集合。当用户创建了一个单聊或群聊,当其中有消息的收发时,对应的会话就随之创建。 - -在腾讯云IM层面,每个会话都是一个 [`V2TIMConversation`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimConversation.html) 类的实例,包括了 `会话类型 / 会话ID / 用户ID / 群ID / 显示名称 / 头像 / 最后一条消息 / 草稿 / 群聊类型 / 消息接收方式 / 群 @ 信息列表 / 是否置顶 / 标记列表 / 所属分组信息 / 自定义数据` 信息。 - -### 会话列表 - -会话列表,您可以理解成微信软件的首页。即,所有会话的集合。方便用户找到目标会话。 - -会话列表功能主要分为获取会话列表、处理会话列表更新。 - -| 会话列表 | -|---------| -| | - -#### 获取会话列表 - -您可在客户端上调用 [`getConversationList`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMConversationManager/getConversationList.html)。该接口获取的是本地缓存的会话,如果服务器会话有更新,SDK 内部会自动同步,然后在 [`V2TIMConversationListener`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Listener/V2TimConversationListener.html) 通知回调。 - -如果您的应用场景会产生较多的会话数,考虑到加载效率、网络省流,我们建议您采用分页拉取的方式。每次分页拉取的数量建议不超过 100 个。[具体方案可参考此处。](https://cloud.tencent.com/document/product/269/75366#.E5.88.86.E9.A1.B5.E6.8B.89.E5.8F.96) - -#### 会话列表实时更新 - -当会话信息发生变化,例如收到一条新消息/设置消息草稿/出现一个新的会话,都会导致会话列表发生更新。 - -如果需要实时获取更新信息,需要通过客户端的 [`addConversationListener`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMConversationManager/addConversationListener.html) 方法,添加会话监听器。收到更新触发后,更改UI。 - -### 会话草稿 - -在发送消息时,可能会遇到消息尚未编辑完,就要切换至其它聊天窗口的情况。 - -这些未编辑完的消息可通过 [`setConversationDraft`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMConversationManager/setConversationDraft.html) 接口保存,以便于下次回到这个聊天界面时,通过 [`V2TIMConversation`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimConversation.html) 对象的 [`draftText`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimConversation.html#drafttext) 字段,获取到尚未编辑完的内容,继续编辑。 - -此类草稿信息,仅保存在本地。 - -### 置顶会话 - -会话置顶指的是把单聊或者群聊会话固定在会话列表的最顶部,不会被其他会话更新挤到底部,方便用户查找。 - -在社交场景中,用户常常需要将一些重要的人或群置顶。这在我们使用微信的过程中,很普遍。 - -置顶状态会存储在服务器,切换终端设备后,置顶状态会同步到新设备上。 - -| 置顶的会话,注意最上方第一条 | -|---------| -| | - -置顶会话,通过客户端 [`pinConversation`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMConversationManager/pinConversation.html) 即可。 - -调用 [`getConversationList`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMConversationManager/getConversationList.html) 获取会话列表时,该接口返回的会话列表中,置顶的会话在前,未置顶的会话在后。您可以通过 [`V2TIMConversation`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimConversation.html) 对象的 [`isPinned`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimConversation.html#ispinned) 字段,检查会话有没有置顶。 - -### 会话标记 - -在某些社交场景下,您可能需要对会话进行标记,例如 "会话标星"、"会话折叠"、"会话隐藏"、“会话标记未读”。 - -直接在客户端调用 [`markConversation`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMConversationManager/markConversation.html) 方法,即可标记,或取消标记一条会话。 - -标记后,在后续通过 [`getConversationListByFilter`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMConversationManager/getConversationListByFilter.html) 方法请求会话列表时,可按照标记,过滤获取指定会话。 - -## 消息 - -消息是社交模块的灵魂。众多各种类型的消息,组成了一个个会话,使得用户与用户之间,紧密的串联在一起。 - -腾讯云IM中,一对一单聊消息与群聊消息,用法在大部分场景中都类似,下面着重介绍几点。 - -### 消息类型 - -腾讯云IM支持多种类型的消息,如下: - -| 功能类型 | 功能描述 | -| ------------ | ------------------------------------------------------------ | -| 文本消息 | 消息内容是普通文本 | -| 表情消息 | 表情消息为开发者自定义,可传入表情资源路径 | -| 地理位置消息 | 消息内容为地理位置标题、经度、纬度信息 | -| 图片消息 | 消息内容为图片的 URL 地址、尺寸、图片大小等信息,最大支持大小为28M的图片 | -| 语音消息 | 消息内容为语音文件的 URL 地址、大小、时长等信息,最大支持大小为28M的语音文件 | -| 文件消息 | 消息内容为文件的 URL 地址、大小、格式等信息,格式不限,最大支持大小为100M的文件 | -| 短视频消息 | 消息内容为短视频文件的 URL 地址、时长、大小、格式等信息,最大支持大小为100M的短视频文件 | -| 自定义消息 | 开发者自定义的消息类型,例如红包消息、石头剪刀布等形式的消息 | - -### 消息回复 - -回复一条消息,既支持使用文字内容,发一条新消息,引用原消息;也支持使用[Emoji表情回应](https://cloud.tencent.com/document/product/269/85906)。 - -| 引用回复文本 | [表情回应](https://cloud.tencent.com/document/product/269/85906) | -|---------|---------| -| | | - -#### 引用回复文本 - -此方案效果和微信中,长按一条消息,选择 “引用”,效果一致。 - -引用消息,实际上,在腾讯云IM SDK层面,也是一条普通文本消息。文本消息的主体,则是回复的文字内容。 - -为了展示原消息的引用,需要在发送文本消息的时候,将原消息的信息,传入新消息的 [`cloudCustomData`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html#cloudcustomdata) 字段中。例如,我们的TUIKit,为了实现这个功能,传入了如下JSON。 - -```json -"messageReply": { - "messageID": 原消息的ID, - "messageAbstract": 原消息的描述,用于显示在消息列表气泡中, - "messageSender": 原消息的发送者,建议使用备注名或昵称, - "messageType": 原消息类型, - "version": 协议版本 -} -``` - -在消息列表中展示时,从 [`cloudCustomData`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html#cloudcustomdata) 字段中,提取出上述JSON信息,直接用于拼接展示 `"${messageSender}: ${messageAbstract}"` 即可。 - -如需支持点击展示引用消息的区域,跳转至被引用原始消息。可根据上述JSON中的 `messageID` 字段,在消息列表中,找到这条消息,跳转即可。如果消息当前不存在于数组中,可直接调用 [`getHistoryMessageList`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/getHistoryMessageList.html),参数传入 `messageID`,获取本条消息及其上下文消息。 - -#### 表情回应 - -在回复特定的单条消息时,你不仅可以直接引用原消息并回复,还可使用Emoji表情回应,高效表达“好的”、“赞同”、“很棒”、“哭笑不得”、“加油”等多种信息,大大降低沟通成本,解决多人聊天中消息冗杂的问题。 - -通常,若干个用户,可对同一条消息,或多条消息,点击一个或若干个回应表情。[在显示上](https://cloud.tencent.com/document/product/269/85906#.E5.B1.95.E7.A4.BA.E8.A1.A8.E6.83.85.E5.9B.9E.E5.BA.94),这些回应信息,常常承载在不同的气泡中,以表情为首,后面跟着若干个名字。如本章节图片所示。 - -这些名称,需要支持点击,并跳转至用户Profile详情页中。若名字过多,还需要加以折叠,[通过新窗口详情页展示](https://cloud.tencent.com/document/product/269/85906#.E5.B1.95.E7.A4.BA.E8.A1.A8.E6.83.85.E5.9B.9E.E5.BA.94)。 - -[发送表情回应](https://cloud.tencent.com/document/product/269/85906#.E5.8F.91.E9.80.81.E8.A1.A8.E6.83.85.E5.9B.9E.E5.BA.94),则可放置于消息的长按菜单中。 - -| 发送表情回应 [TUIKit](https://cloud.tencent.com/document/product/269/85906) | 表情回应详情 [TUIKit](https://cloud.tencent.com/document/product/269/85906) | -|---------|---------| -| | | - -**下面介绍实施细节:** - -表情回应的数据,存储于消息的 [`cloudCustomData`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html#cloudcustomdata) 字段中,可以如下JSON格式示例。其中的 `key` 字段,如采用Emoji Unicode表情字符,可直接传入 Unicode;若采用图片小表情,可传入路径或文件名。 - -```json -messageReactions: [ - { - key: "表情名称1", - users: ["用户1", "用户2", ...] - }, - { - key: "表情名称2", - users: ["用户1", "用户2", ...] - }, - ... -] -``` - -本部分代码可根据您的需求,加以修改。 - -展示时,渲染遍历上述结构体即可。 - -发送表情回应,则直接在客户端调用 [`modifyMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/modifyMessage.html) 方法,修改消息本身的 [`cloudCustomData`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html#cloudcustomdata) 字段即可。将当前用户头像,添加或从上述结构体中移除,完成回应或取消回应。 - -调用方法修改后,所有用户的 [`V2TimAdvancedMsgListener`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Listener/V2TimAdvancedMsgListener.html) => [`onRecvMessageModified`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Callback/OnRecvMessageModified.html) 监听器会触发,您可依此修改消息UI,展示最新表情回应内容。 - -### 删除消息 - -删除消息分为两种:删除本地消息和删除云端消息。 - -删除云端消息会在删除本地消息的基础上,同步删除云端存储的消息,且无法恢复。 - -删除本地消息,在客户端调用 [`deleteMessageFromLocalStorage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/deleteMessageFromLocalStorage.html) 方法。需要注意的是,如果程序卸载重装,依旧能获取到被删除的消息。 - -删除云端存储的消息,在客户端调用 [`deleteMessages`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/deleteMessages.html) 方法。此方法不支持多端同步,即无法自动删除,其他设备上,已经存在的消息。 - -### 搜索消息 - -搜索能力是社交场景中的重要一环。 - -用户们常常需要,在特定会话中,亦或是全局中,快速准确搜索到某条消息。此外,也可作为社交活动运营工具,增加相关内容的引导,简洁高效。 - -您可在客户端,调用 [`searchLocalMessages`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/searchLocalMessages.html) 方法,并传入以 [`V2TIMMessageSearchParam`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessageSearchParam.html) 对象封装的关键词信息,即可完成搜索。 - -如果您希望在全部会话范围内搜索,只需要将 [`V2TIMMessageSearchParam`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessageSearchParam.html) 中的 [`conversationID`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessageSearchParam.html#conversationid) 设置为空或者不设置即可。 - -| 全局搜索 | 会话内搜索 | -|---------|---------| -| | | - -### 转发消息 - -在日常生活聊天或工作场景中,将一个会话中的消息,合并或逐条转发至另一个会话,是个非常高频且基础的操作。 - -| 合并转发消息 | 合并消息详细内容 | -|---------|---------| -| | | - -逐条转发消息,需要先在客户端调用 [`createForwardMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/createForwardMessage.html) 方法创建一条和原消息内容完全一样的转发消息,再调用 [`sendMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/sendMessage.html) 方法把转发消息发送出去。 - -合并转发消息,同样需要先创建后转发。需要额外注意的是,在客户端调用 [`createMergerMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/createMergerMessage.html) 方法创建一条合并消息时,需要设置原始消息列表,合并消息标题、合并消息摘要等信息。 - -若想转发至多个接收者,遍历调用 [`sendMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/sendMessage.html) 方法即可。 - -对于接收者端,若想展示上方右侧图片的合并消息详情,需要当用户点击合并消息的时候再调用 [`downloadMergerMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/downloadMergerMessage.html) 方法下载合并消息列表 UI 展示。 - -### 撤回消息 - -消息撤回是目前社交软件中必备的功能。 - -发送方可撤回一条已经发送成功的消息。默认情况下,发送者只能撤回 2 分钟以内的消息,此配置可按需修改。 - -撤回方在客户端,调用 [`revokeMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/revokeMessage.html) 方法,接收方会收到消息撤回通知 [`onRecvMessageRevoked`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Callback/OnRecvMessageRevokedCallback.html)。通知中包含了撤回消息的 msgID,您可根据这个 msgID 判断 UI 层是哪一条消息撤回了,然后把对应的消息气泡切换成 "消息已被撤回" 状态。 - -### 消息翻译 - -对于国际化的聊天场景,消息翻译功能必不可少,可大大提升跨语言交流效率。社交场景中,大型群聊内,有不同语言的交流存在,是非常之常见的。 - -| 消息翻译 | -|---------| -| | - -对于文本类型的消息,您可在客户端上调用 [`translateText`](https://im.sdk.qcloud.com/doc/zh-cn/classcom_1_1tencent_1_1imsdk_1_1v2_1_1V2TIMMessageManager.html#a1e1806c27bc7b76a3b816492ed9cbe5c) 方法,将待翻译文本列表和目标语言传至我们的服务端。原语言可由您自行判断,也可由我们判断。 - -翻译结果返回后,我们建议您将其通过客户端的 [`setLocalCustomData`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/setLocalCustomData.html) 方法,存放于消息的 [`localCustomData`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html#localcustomdata) 字段中,以便于后续直接展示,避免用户重复翻译,多次发送翻译请求。 - -我们支持众多语言的互相翻译,[所有支持的语言可查看此处](https://cloud.tencent.com/document/product/269/85380#.E6.96.87.E6.9C.AC.E7.BF.BB.E8.AF.91.E8.AF.AD.E8.A8.80.E6.94.AF.E6.8C.81)。 - -### 消息已读回执 - -单聊和群聊均支持消息已读回执功能,操作步骤一致。 - -| 单聊,[TUIKit](https://cloud.tencent.com/document/product/269/85905)中以文字承载 | 群聊,[TUIKit](https://cloud.tencent.com/document/product/269/85905)中以圆圈承载 | -|---------|---------| -| | | - - -是否启用此功能,可根据您的社交业务需求决定。 - -例如对于类似微信的熟人社交,已读回执的用处可能不是非常大;但是对于陌生人交友场景,已读回执则十分重要,帮助用户来确认,对方是否愿意跟自己聊下去,是否已读不回;对于工作聊天场景,群已读回执还能发挥更大的作用,可便捷看到群内哪些人已读哪些人未读,帮助发送者确认信息传递效率。 - -**具体用法如下:** - -发送端创建消息后,先通过消息对象 [`V2TIMMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html) 的 [`needReadReceipt`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html#needreadreceipt) 字段设置这条消息需要已读回执,再发送消息到会话中。 - -接收端收到消息后,根据消息对象 [`V2TIMMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html) 的 [`needReadReceipt`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Message/V2TimMessage.html#needreadreceipt) 字段判断消息是否需要已读回执。如果需要,当用户查看消息后,调用 `sendMessageReadReceipts` 方法发送消息已读回执。 - -接收端发送消息已读回执后,发送端可在 [`V2TIMAdvancedMsgListener`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Class/Listener/V2TimAdvancedMsgListener.html) 的 [`onRecvMessageReadReceipts`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Callback/OnRecvMessageReadReceipts.html) 中收到已读回执通知,在通知中更新 UI,例如更新某条消息为 “2 人已读”。 - -此外,发送端也可主动请求消息已读回执信息。发送端从其他界面进入消息列表后,先请求获取历史消息,再调用 [`getMessageReadReceipts`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/getMessageReadReceipts.html) 方法请求获取消息已读回执信息。 - -群聊场景的消息已读回执,通常需要能够查看详情,显示群内哪些人已读,哪些人未读。当用户点击已读回执角标时,可调用 [`getGroupMessageReadMemberList`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/getGroupMessageReadMemberList.html) 方法分页拉取消息已读或未读群成员列表。 - -| 已读 群成员 | 未读 群成员 | -|---------|---------| -| | | - -### 群内@消息 - -相信大家已经很熟悉,在群聊交流过程中,如果需要提及或提醒某些群成员,我们可直接 @ 他们。所有的社交聊天软件,都有这个基础功能。 - -当用户输入 @ 字符后,弹出群成员选择界面。选择完需要 @ 的成员后以 “@A @B @C......” 形式显示在输入框,并可继续编辑消息内容,完成消息发送。 - -| 监听 @ 字符选择群成员 | 编辑群 @ 消息发送 | 收到群 @ 消息 | -|---------|---------|---------| -| | | | - ->? 图一:在聊天界面监听到输入框输入 "@" 字符后,可跳转到群成员选择界面,选择需要 @ 的群成员。 ->图二:在群成员选择完成后,重新返回聊天界面,继续编辑群 @ 消息发送。 ->图三:如果有消息 @ 我,自己会收到会话更新,可在会话 Cell 展示 “有人@我” 信息。 - -由于实现方案内容较多,[您可查看此文档](https://cloud.tencent.com/document/product/269/75349),获取详情。 - -### 消息漫游 - -如果用户有多台设备,或者同时使用电脑和手机登录您的应用程序,用户们希望看到,无论在哪一端,历史消息都能尽可能完整。能从提供的历史消息上下文中,快速无障碍的加入聊天,满足社交场景高频率聊天的要求。 - -为了保证交流的连续性与流畅性,我们提供一套消息漫游存储能力,即用户更换终端的情况下,也可以获取到跟其他用户或者某个群的聊天记录,可以达到类似QQ软件的效果。 - -默认情况下,单聊消息和群聊消息有7天漫游,超过漫游时长的消息会被删除。此外,还支持在控制台修改消息漫游时长,延长消息漫游时长是增值服务。 - -以下截图演示了消息在手机和电脑之间漫游。*图片来自Flutter TUIKit,一套代码完成电脑桌面端/Web端/移动端应用的开发。* - -| 电脑端 | 手机移动端 | -|---------|---------| -| | | - -### 更多丰富的消息形态 - -我们默认提供的消息类型,可满足您大部分的聊天场景需求。但是对于社交软件来说,仅有这些还远远不够。 - -红包/送礼物/投票/发送匹配度/闪照等等一系列创新玩法,让您app的社交场景模块变得更加丰富多彩。 - -因此,您可使用我们提供的**自定义消息**能力,来发挥您的想象力,尽情创造激动人心的玩法及贴合您业务需求的功能。 - -发送自定义消息分两步: - -- 调用 [`createCustomMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/createCustomMessage.html) 创建自定义消息,传入消息体。 -- 调用 [`sendMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/sendMessage.html) 发送消息。 - -消息体中,您可以JSON格式,传入任何符合您需求的数据。例如,包含一个字段控制消息形态类型,还包含一个字段控制消息当前数据。 - -如果是投票/红包等类型的消息,如果您想实时更新投票数据/红包领取信息,可将此类信息放在消息体中,在客户端上,通过 [`modifyMessage`](https://comm.qq.com/im/doc/flutter/zh/SDKAPI/Api/V2TIMMessageManager/modifyMessage.html) 方法实时修改。 - -## 更多能力 - -### 内容审核 - -在社交场景中,用户很可能会发送不合规的消息。特别是陌生人交友软件,黄色不良内容消息更是频频出现。诱导性暗示图片/裸聊等令人反感的内容,不仅严重损害了用户们的身心健康,更很有可能违法并导致应用被监管部门查封。 - -我们支持内容审核(反垃圾信息)功能,可针对不安全、不适宜的内容进行自动识别、处理,为您的产品体验和业务安全保驾护航。 - -目前有以下三种内容审核方式。 - -| 方式 | 介绍 | -|---------|---------| -| [本地审核](https://cloud.tencent.com/document/product/269/79139#bdsh) | 在客户端本地检测由即时通信 SDK 发送的文本内容,支持对已配置的敏感词进行拦截或者替换处理。此功能通过在 IM 开启服务并配置词库的方式实现。 | -| [云端审核](https://cloud.tencent.com/document/product/269/79139#ydsh) | 在服务端检测由单聊、群聊、资料场景中产生的文本、图片、音频、视频内容,支持针对不同场景的不同内容分别配置审核策略,并对识别出的不安全内容进行拦截。 | -| [第三方回调服务](https://cloud.tencent.com/document/product/269/79139#dsf) | 如果您已接入第三方内容审核服务,您可以使用 第三方回调配置 来实现。 | - -您可按需使用如上三种内容审核工具,保证业务安全运行。 - -### 离线推送 - -社交场景下,用户需要随时都能够得知最新的消息,以加快聊天效率,促进社交关系的形成。 - -由于移动端设备的性能与电量有限,当 App 处于后台时,为了避免维持长连接而导致的过多资源消耗,我们推荐您使用各厂商提供的系统级推送通道来进行消息通知。系统级的推送通道相比第三方推送拥有更稳定的系统级长连接,可以做到随时接受推送消息,且资源消耗大幅降低。 - -我们目前原生支持的厂商系统有:苹果iOS/Google FCM/OPPO/VIVO/华为/小米/魅族/荣耀。 - -理论上,集成系统原生的离线推送,需要手动对接各个厂商的SDK,手动注册服务/获取Token/承载点击回调页面,非常之复杂。 - -因此,我们提供了如下几款离线推送插件,封装了上述厂商的原生SDK,大大降低了使用上手成本。您可直接按照文档配置。开箱即用。 - -- [Native](https://cloud.tencent.com/document/product/269/74285) -- [Flutter](https://cloud.tencent.com/document/product/269/74605) -- [uni-app](https://cloud.tencent.com/document/product/269/79124) - -![](https://qcloudimg.tencent-cloud.cn/raw/58f36a132a9fa46b84b12070777b8e9b.png) - -### 音视频通话 - -许多时候,仅靠文字和图片还是不足以抒发我们内心的情感,可能打字聊天一小时,也比不是直接打一通视频电话来的爽快。 - -特别是对于社交场景下的用户们,他们一定有很多想法想要交流与诉说。 - -因此,我们也强烈推荐您,再集成我们的音视频通话能力,一步到位,完成一对一或多人群组的音频/视频通话,并且支持离线唤起能力。 - -[详情可查看此文档](https://cloud.tencent.com/document/product/269/84296)。 - -![](https://qcloudimg.tencent-cloud.cn/raw/08f914b45857743fd05dfaa28e2adb72.png) - -以上,就是使用腾讯云IM实现社交场景常见需求的解决方案。快来使用腾讯云IM打造属于您的社交产品吧~ diff --git a/example/.metadata b/example/.metadata index 5a02328..212e4a0 100644 --- a/example/.metadata +++ b/example/.metadata @@ -1,10 +1,36 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled and should not be manually edited. +# This file should be version controlled. version: - revision: 7e9793dee1b85a243edd0e06cb1658e98b077561 + revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 channel: stable project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + - platform: linux + create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + - platform: macos + create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + - platform: windows + create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/example/1400187352_3130303435333633/im.db b/example/1400187352_3130303435333633/im.db new file mode 100644 index 0000000000000000000000000000000000000000..84687bc268a0c0a55103c2ec9e0331483f4a5ecf GIT binary patch literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WYCM3;RR_IAlr;ljiVtj n8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O6ovo*N!bRB literal 0 HcmV?d00001 diff --git a/example/1400187352_3130303435333633/im.db-shm b/example/1400187352_3130303435333633/im.db-shm new file mode 100644 index 0000000000000000000000000000000000000000..722a46cdd2f9accb03c9aa29f3b8f892c4b3da0a GIT binary patch literal 32768 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 @1Wry{$k&Ue~Iv2OC;6Lvf4i-teSYjy376x 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

|w+5-HqK zUDw=fvpVaPdjwizeQl$w%GIE}K%iCF8k)S#wN*-`Ky&#T+58>KjRLLK+gt~|qf!|X zXf>5?6ZG;%w$(^M|4Ii++p$6IIXQ9?^g)4swS`9SMPEvbpp-Ap;w{2 zP(-u2EiSl^`rkOs*kNs}X|g&ym6r&#TDQ9yWU-t&5vQ4&Y&GR(2h^-zpj9+=w3j!y zEJ~F?bJ!c~9cT>ch|`R2kGTojz@e-ZXzfj{<(4*(j7EW0Yi>sJ?ojR)XwB_S4ya$F z@|rl!Bm z&|1tL?SMh0vOP{SSvgD{$}WLc$tR^y)(A9PdtEK?QKf7UXjN?hN;{0zJtCURV{L4Q zaivb6Rr;DNP;Rv{DA3G}bxw=bSxfyRPBXSyI_n`#s89JNfmYt?Gr?R^rEC&tZPm4C zTyZKp1zJmOli5>OTdCYD(CS(%tD!sBQ8mAfUCJ&m|Jk+lRT7$)EbJzfTZ=7aswYQ))Hz}`<(@Y+BZF?n>wWvUAD{pOU zD2MrK2zrJVjagVP;9Pv|+r3ZC`884&X!Q3Gu>UWi=j%V9PtZ5$e?o84-$Or*?w7tK z1SA9`1SA9`1SA9`1SA9`1SA9`1SA9`1U@SS@)h}IB&∨th9dzX45(J5w9pt8*3k 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 z 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

K?LJvE`Mjp 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 literal 0 HcmV?d00001 diff --git a/example/1400187352_3130303435333633/msg_0.db-shm b/example/1400187352_3130303435333633/msg_0.db-shm new file mode 100644 index 0000000000000000000000000000000000000000..015c0c02fab0de05efcdc953dd8bb674303ec13f GIT binary patch literal 32768 zcmeI5b&yw86vsbz1D0OcUD%*43^2gJM#b)03me4_?80uvZpFgDzycGyP;3D^u)D=o zbUkO7JM-qv`g3quN8kINne)5n-Fxo2=X~D#&FmlhJFj|1e_YB;1C;l*j~-?ZA31i& zn9;Q}r;Mv_7+TiYZ`y#V4YMZKkFTCXe~<0raT^mdd)5xLc^4mwOp8rRnz$~txmKpF zO+D8(rfp5znYK6WVA|2NlWC0cZ`kR){mk-24$ZaG@jEACM>~$rt&pAM8}lsWA36RL zpLE_`EVroXHD}~!`1)U+na&{{Bkql(vxs&a=VUIOkH<)!>DLvhxyV1R#ai4i$v(#R z`J|8A>AB>YzE)|PoQpNZwHVL++-}Oh%I3S8b~CLutud`NtuyUz>fe8l>wZ3;wBy;n z7WXH8Jf5%l827o|)IL8q`nVl^e9rSuo)L3Q`X_DQo80fuRNS9D$8(Mv_s44=B_bdK zA|L`HAOa#F0wN#+A|L`HAOa#F0wN#+A|L`HAOa#F0wN#+A|L`HAOa#F0wN#+A|L`H zAOa#F0wN#+A|L`HAOa#F0wN#+A|L`HAOa#F0wN#+A}}`zygfIAWja=%lto#C137{- z7{_>?VhXSE1q~F1&Y_F{q+Ig9BJd7hGmF-tTc``&Lyyoq^a@WF1u&V@vH0UNO?^=!@d?8GkY#-8lM{v6Cv9LI^A%4p8vJTBy7 zF5?QW;u@~!W^QL9_wf*q@;H-uo>!R08wK*wQu7JC#~*~yCUgkpp;}LW0iY$;MXSoX z^wiOlKFrGkEJS~nU?~Q(JS(vZLs^^k*qF`Of^FD=o!OP$*^7M{$svs5cuwLp&f745rKRX@Q(Kq5y&S2?}slDfqWA1H*QEoAfE*MeKZmg$R~jcd)HBoz1OH0eVLDb zEX)7~GAy4kRCUe>3}R`PWd&AdRaR$Pj;2cg9g?$WAiw3V!}@HSh<1e_F literal 0 HcmV?d00001 diff --git a/example/1400187352_3130303435333633/msg_0.db-wal b/example/1400187352_3130303435333633/msg_0.db-wal new file mode 100644 index 0000000000000000000000000000000000000000..c5a8d0a46e876de001a534ba83f9b0a1928a3ce4 GIT binary patch literal 1194832 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 z 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

&M3x7G! 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 AVgLXD literal 0 HcmV?d00001 diff --git a/example/imsdk_C_20221229.xlog b/example/imsdk_C_20221229.xlog new file mode 100644 index 0000000000000000000000000000000000000000..c27d09523610c05a6b47dacbab06f8002bae04e6 GIT binary patch literal 211494 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 WW#Q@bmer+S@7T29_8Hn4QnHE=Ys z)HO6PG}bkAa&^>oG;lU`ax}GYHny0uWb0fuhZ~o#%x3lCFf=eQF*Pg`x(3z{CXl($Z3hL4@|9Prlf1*40cRbY2GT zIp4YGJBRC8?^%sdghhhLq6o(#QS{wjSyP5EMzt=_N1hK55?G$+S%i2tBKWRlmVos^ z)}G`54+_5FhIimP&ng5UoC^XgBB$tDk5`DWA}az6Low$}5#U3B@ZsfmA(0L9EH4CE z6y}|Rw#$0(&LKcUY?yNxsr;F#`1RTB`SQvN#Bo9>7!Fn+dwy|#;bft(!r$EV;g6em zS6S!iy-$a}pud$b)OEXF3^wdOHqkyf@YUAonW;P8)Y+lEdp586tN-}?=O;d%T;KLs zoA0}Mf9UI~qwX7_o%=e!%kS9S{B+CAPuCt+wSCgw^zFufrv}qO@8#dWIps|@l!rE? zTdt1RFw?(mjh{KW4f^sIN_-1P^v{AJag_shC9bC-Sy`Ra#f=U$1tPwddPH5_P+ z#sO4tXfjZ zyRraTY!M;nUGLYi%%!6%6m)de$TW{#m>6-#m_z5wDhluok1>@4Wqp2=7`jQZs&`?P zkoD{B-(%4#N&WH6cqk4fFc z8A7O{bpek9gK`|xRFRR9dNGwOSgn^NvQ*JEOqGnC9lVqhHL1YPma1ejpkObbRBWNX ze#fekmQP4vT#{uIQUutx6%7R7nZomD;W3A}Ku!oW6~}iG+L}uQ;J4o(T5Ie6-LV!s zKd|U_~b92O9`^Wc8=bw+xw4`3YzFXi7SMRII@ey}{ Q8UOp%i2F3-8fIMo0XTkp&j0`b literal 0 HcmV?d00001 diff --git a/example/imsdk_sensitive_word_1400187352 b/example/imsdk_sensitive_word_1400187352 new file mode 100644 index 0000000..b8faf10 --- /dev/null +++ b/example/imsdk_sensitive_word_1400187352 @@ -0,0 +1,2 @@ + +Hϼhѽ#%-a \ No newline at end of file diff --git a/example/ios/Podfile b/example/ios/Podfile index 1e8c3c9..313ea4a 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' +platform :ios, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 68bacaa..4bd8450 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,17 +1,18 @@ PODS: - - camera (0.0.1): + - audioplayers_darwin (0.0.1): - Flutter - - connectivity_plus (0.0.1): + - camera_avfoundation (0.0.1): - Flutter - - ReachabilitySwift - - DKImagePickerController/Core (4.3.3): + - disk_space (0.0.1): + - Flutter + - DKImagePickerController/Core (4.3.4): - DKImagePickerController/ImageDataManager - DKImagePickerController/Resource - - DKImagePickerController/ImageDataManager (4.3.3) - - DKImagePickerController/PhotoGallery (4.3.3): + - DKImagePickerController/ImageDataManager (4.3.4) + - DKImagePickerController/PhotoGallery (4.3.4): - DKImagePickerController/Core - DKPhotoGallery - - DKImagePickerController/Resource (4.3.3) + - DKImagePickerController/Resource (4.3.4) - DKPhotoGallery (0.0.17): - DKPhotoGallery/Core (= 0.0.17) - DKPhotoGallery/Model (= 0.0.17) @@ -35,11 +36,18 @@ PODS: - DKPhotoGallery/Resource (0.0.17): - SDWebImage - SwiftyGif + - fc_native_video_thumbnail_for_us (0.0.1): + - Flutter - file_picker (0.0.1): - DKImagePickerController/PhotoGallery - Flutter - Flutter (1.0.0) - - flutter_plugin_record (0.0.1): + - flutter_image_compress (1.0.0): + - Flutter + - Mantle + - SDWebImage + - SDWebImageWebPCoder + - flutter_plugin_record_plus (0.0.1): - Flutter - fluttertoast (0.0.2): - Flutter @@ -52,69 +60,98 @@ PODS: - Flutter - image_picker_ios (0.0.1): - Flutter - - libwebp (1.2.1): - - libwebp/demux (= 1.2.1) - - libwebp/mux (= 1.2.1) - - libwebp/webp (= 1.2.1) - - libwebp/demux (1.2.1): + - libwebp (1.2.4): + - libwebp/demux (= 1.2.4) + - libwebp/mux (= 1.2.4) + - libwebp/webp (= 1.2.4) + - libwebp/demux (1.2.4): - libwebp/webp - - libwebp/mux (1.2.1): + - libwebp/mux (1.2.4): - libwebp/demux - - libwebp/webp (1.2.1) - - open_file (0.0.1): - - Flutter + - libwebp/webp (1.2.4) + - Mantle (2.2.0): + - Mantle/extobjc (= 2.2.0) + - Mantle/extobjc (2.2.0) - package_info_plus (0.4.5): - Flutter - - path_provider_ios (0.0.1): + - pasteboard (0.0.1): - Flutter - - "permission_handler (5.1.0+2)": + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - permission_handler_apple (9.0.4): - Flutter - photo_manager (2.0.0): - Flutter - FlutterMacOS - - ReachabilitySwift (5.0.0) - - SDWebImage (5.12.5): - - SDWebImage/Core (= 5.12.5) - - SDWebImage/Core (5.12.5) - - shared_preferences_ios (0.0.1): + - ReactiveObjC (3.1.1) + - SDWebImage (5.15.5): + - SDWebImage/Core (= 5.15.5) + - SDWebImage/Core (5.15.5) + - SDWebImageWebPCoder (0.11.0): + - libwebp (~> 1.0) + - SDWebImage/Core (~> 5.15) + - shared_preferences_foundation (0.0.1): - Flutter + - FlutterMacOS - sqflite (0.0.2): - Flutter - FMDB (>= 2.7.5) - - SwiftyGif (5.4.3) - - tencent_im_sdk_plugin (1.0.5): + - SwiftyGif (5.4.4) + - tencent_cloud_chat_sdk (5.1.2): - Flutter - HydraAsync - - TXIMSDK_Plus_iOS (= 6.1.2155.1) + - TXIMSDK_Plus_iOS (= 7.1.3925) + - tencent_cloud_uikit_core (0.0.1): + - Flutter + - TUICore (= 7.1.3925) + - tencent_open_file (0.0.1): + - Flutter - Toast (4.0.0) - - TXIMSDK_Plus_iOS (6.1.2155.1) + - TUICore (7.1.3925): + - ReactiveObjC + - SDWebImage + - TUICore/ImSDK_Plus (= 7.1.3925) + - TUICore/Base (7.1.3925): + - ReactiveObjC + - SDWebImage + - TUICore/ImSDK_Plus (7.1.3925): + - ReactiveObjC + - SDWebImage + - TUICore/Base + - TXIMSDK_Plus_iOS (= 7.1.3925) + - TXIMSDK_Plus_iOS (7.1.3925) + - url_launcher_ios (0.0.1): + - Flutter - video_player_avfoundation (0.0.1): - Flutter - - video_thumbnail (0.0.1): - - Flutter - - libwebp - wakelock (0.0.1): - Flutter DEPENDENCIES: - - camera (from `.symlinks/plugins/camera/ios`) - - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) + - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`) + - camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`) + - disk_space (from `.symlinks/plugins/disk_space/ios`) + - fc_native_video_thumbnail_for_us (from `.symlinks/plugins/fc_native_video_thumbnail_for_us/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) - - flutter_plugin_record (from `.symlinks/plugins/flutter_plugin_record/ios`) + - flutter_image_compress (from `.symlinks/plugins/flutter_image_compress/ios`) + - flutter_plugin_record_plus (from `.symlinks/plugins/flutter_plugin_record_plus/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - - open_file (from `.symlinks/plugins/open_file/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) + - pasteboard (from `.symlinks/plugins/pasteboard/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - photo_manager (from `.symlinks/plugins/photo_manager/ios`) - - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - - tencent_im_sdk_plugin (from `.symlinks/plugins/tencent_im_sdk_plugin/ios`) + - tencent_cloud_chat_sdk (from `.symlinks/plugins/tencent_cloud_chat_sdk/ios`) + - tencent_cloud_uikit_core (from `.symlinks/plugins/tencent_cloud_uikit_core/ios`) + - tencent_open_file (from `.symlinks/plugins/tencent_open_file/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`) - - video_thumbnail (from `.symlinks/plugins/video_thumbnail/ios`) - wakelock (from `.symlinks/plugins/wakelock/ios`) SPEC REPOS: @@ -124,83 +161,104 @@ SPEC REPOS: - FMDB - HydraAsync - libwebp - - ReachabilitySwift + - Mantle + - ReactiveObjC - SDWebImage + - SDWebImageWebPCoder - SwiftyGif - Toast + - TUICore - TXIMSDK_Plus_iOS EXTERNAL SOURCES: - camera: - :path: ".symlinks/plugins/camera/ios" - connectivity_plus: - :path: ".symlinks/plugins/connectivity_plus/ios" + audioplayers_darwin: + :path: ".symlinks/plugins/audioplayers_darwin/ios" + camera_avfoundation: + :path: ".symlinks/plugins/camera_avfoundation/ios" + disk_space: + :path: ".symlinks/plugins/disk_space/ios" + fc_native_video_thumbnail_for_us: + :path: ".symlinks/plugins/fc_native_video_thumbnail_for_us/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" Flutter: :path: Flutter - flutter_plugin_record: - :path: ".symlinks/plugins/flutter_plugin_record/ios" + flutter_image_compress: + :path: ".symlinks/plugins/flutter_image_compress/ios" + flutter_plugin_record_plus: + :path: ".symlinks/plugins/flutter_plugin_record_plus/ios" fluttertoast: :path: ".symlinks/plugins/fluttertoast/ios" image_gallery_saver: :path: ".symlinks/plugins/image_gallery_saver/ios" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" - open_file: - :path: ".symlinks/plugins/open_file/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" - path_provider_ios: - :path: ".symlinks/plugins/path_provider_ios/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" + pasteboard: + :path: ".symlinks/plugins/pasteboard/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/ios" + permission_handler_apple: + :path: ".symlinks/plugins/permission_handler_apple/ios" photo_manager: :path: ".symlinks/plugins/photo_manager/ios" - shared_preferences_ios: - :path: ".symlinks/plugins/shared_preferences_ios/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/ios" sqflite: :path: ".symlinks/plugins/sqflite/ios" - tencent_im_sdk_plugin: - :path: ".symlinks/plugins/tencent_im_sdk_plugin/ios" + tencent_cloud_chat_sdk: + :path: ".symlinks/plugins/tencent_cloud_chat_sdk/ios" + tencent_cloud_uikit_core: + :path: ".symlinks/plugins/tencent_cloud_uikit_core/ios" + tencent_open_file: + :path: ".symlinks/plugins/tencent_open_file/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" video_player_avfoundation: :path: ".symlinks/plugins/video_player_avfoundation/ios" - video_thumbnail: - :path: ".symlinks/plugins/video_thumbnail/ios" wakelock: :path: ".symlinks/plugins/wakelock/ios" SPEC CHECKSUMS: - camera: 9993f92f2c793e87b65e35f3a23c70582afb05b1 - connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e - DKImagePickerController: 72fd378f244cef3d27288e0aebf217a4467e4012 + audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 + camera_avfoundation: 07c77549ea54ad95d8581be86617c094a46280d9 + disk_space: e94d34bbdf77954adfb39e60bde9cc5c7233eda6 + DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 - file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 - Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a - flutter_plugin_record: 562ded56f3a109d769e72c3ef52ef20d835493d4 - fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037 + fc_native_video_thumbnail_for_us: 69559e6500bff0f6340f044ec0847366fa6f6233 + file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95 + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + flutter_image_compress: 5a5e9aee05b6553048b8df1c3bc456d0afaac433 + flutter_plugin_record_plus: 79b8e13ee7ed9a94f6c067018653599528cee1fc + fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a HydraAsync: 8d589bd725b0224f899afafc9a396327405f8063 image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb - libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc - open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d + libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef + Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e - path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 - permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 + pasteboard: 982969ebaa7c78af3e6cc7761e8f5e77565d9ce0 + path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604 - ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 - SDWebImage: 0905f1b7760fc8ac4198cae0036600d67478751e - shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad + ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040 + SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe + SDWebImageWebPCoder: 295a6573c512f54ad2dd58098e64e17dcf008499 + shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 - SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 - tencent_im_sdk_plugin: c68993c62fd0198cd47132a055a06c9cef33b8e3 + SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f + tencent_cloud_chat_sdk: 17f2ddd7de43495312603e7c9dac04d76352e246 + tencent_cloud_uikit_core: 2c4ccb41c33b45b5c69750b9774fa389fc20cdb2 + tencent_open_file: 1261db508715b8f43ef3b7e31c90824838038165 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 - TXIMSDK_Plus_iOS: 2b0e9440eacdb49f385c90a23ad6558013f0cac6 + TUICore: edc9e0911f6a04224620d7098ff9d7f4b1f0291a + TXIMSDK_Plus_iOS: 3edf95acc3dff794287ea858b5205ed6f4dd339f + url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2 video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff - video_thumbnail: c4e2a3c539e247d4de13cd545344fd2d26ffafd1 wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f -PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c +PODFILE CHECKSUM: 7368163408c647b7eb699d0d788ba6718e18fb8d -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.0 diff --git a/example/lib/TIMUIKitChatExample.dart b/example/lib/TIMUIKitChatExample.dart index baeed5c..d82bb9f 100644 --- a/example/lib/TIMUIKitChatExample.dart +++ b/example/lib/TIMUIKitChatExample.dart @@ -3,7 +3,6 @@ import 'package:example/TIMUIKitGroupProfileExample.dart'; import 'package:example/TIMUIKitProfileExample.dart'; import 'package:flutter/material.dart'; -import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; class TIMUIKitChatExample extends StatelessWidget { @@ -12,21 +11,60 @@ class TIMUIKitChatExample extends StatelessWidget { const TIMUIKitChatExample({Key? key, this.selectedConversation}) : super(key: key); - String? _getConversationID() { - if(selectedConversation != null){ - return selectedConversation!.type == 1 - ? selectedConversation!.userID - : selectedConversation!.groupID; - } - return null; + Widget renderCustomStickerPanel({ + sendTextMessage, + sendFaceMessage, + deleteText, + addCustomEmojiText, + addText, + List defaultCustomEmojiStickerList = const [], + double? height, + double? width + }) { + final defaultEmojiList = + defaultCustomEmojiStickerList.map((customEmojiPackage) { + return CustomStickerPackage( + name: customEmojiPackage.name, + baseUrl: "assets/custom_face_resource/${customEmojiPackage.name}", + isEmoji: customEmojiPackage.isEmoji, + isDefaultEmoji: true, + stickerList: customEmojiPackage.list + .asMap() + .keys + .map((idx) => + CustomSticker(index: idx, name: customEmojiPackage.list[idx])) + .toList(), + menuItem: CustomSticker( + index: 0, + name: customEmojiPackage.icon, + )); + }).toList(); + return StickerPanel( + sendTextMsg: sendTextMessage, + sendFaceMsg: (index, data) => + sendFaceMessage(index + 1, (data.split("/")[3]).split("@")[0]), + deleteText: deleteText, + addText: addText, + addCustomEmojiText: addCustomEmojiText, + customStickerPackageList: [ + ...defaultEmojiList, + ]); } @override Widget build(BuildContext context) { return TIMUIKitChat( + conversation: selectedConversation ?? + V2TimConversation( + conversationID: "c2c_10040818", + userID: "10040818", + showName: "Test Chat", + type: 1), + customStickerPanel: renderCustomStickerPanel, config: const TIMUIKitChatConfig( // 仅供演示,非全部配置项,实际使用中,可只传和默认项不同的参数,无需传入所有开关 isAllowClickAvatar: true, + isUseDefaultEmoji: true, isAllowLongPressMessage: true, isShowReadingStatus: true, isShowGroupReadingStatus: true, @@ -38,12 +76,6 @@ class TIMUIKitChatExample extends StatelessWidget { GroupReceiptAllowType.public ], ), - conversation: selectedConversation ?? - V2TimConversation( - conversationID: "c2c_10040818", - userID: "10040818", - showName: "Test Chat", - type: 1), appBarConfig: AppBar( actions: [ IconButton( diff --git a/example/lib/TIMUIKitSearchExample.dart b/example/lib/TIMUIKitSearchExample.dart index d547e53..078e6ae 100644 --- a/example/lib/TIMUIKitSearchExample.dart +++ b/example/lib/TIMUIKitSearchExample.dart @@ -10,8 +10,6 @@ class TIMUIKitSearchExample extends StatelessWidget { Widget build(BuildContext context) { return TIMUIKitSearch( onTapConversation: (conv, message) { - print(conv.toJson()); - print(message!.toJson()); }, onEnterConversation: (V2TimConversation conversation, String keyword) {}, ); diff --git a/example/lib/main.dart b/example/lib/main.dart index 10fee08..eb814ac 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -39,7 +39,7 @@ class MyApp extends StatelessWidget { // is not restarted. primarySwatch: Colors.blue, ), - home: const MyHomePage(title: 'Tencent IM UIKit'), + home: const MyHomePage(title: 'Tencent Cloud Chat UIKit'), ); } } @@ -67,7 +67,7 @@ class _MyHomePageState extends State { } String getUserID() { - return const String.fromEnvironment('LOGINUSERID', defaultValue: ""); + return const String.fromEnvironment('LOGINUSERID', defaultValue: "10045363"); } String getSecret() { diff --git a/example/linux/.gitignore b/example/linux/.gitignore new file mode 100644 index 0000000..d3896c9 --- /dev/null +++ b/example/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/example/linux/CMakeLists.txt b/example/linux/CMakeLists.txt new file mode 100644 index 0000000..74c66dd --- /dev/null +++ b/example/linux/CMakeLists.txt @@ -0,0 +1,138 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "example") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.example") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/example/linux/flutter/CMakeLists.txt b/example/linux/flutter/CMakeLists.txt new file mode 100644 index 0000000..d5bd016 --- /dev/null +++ b/example/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/example/linux/flutter/generated_plugin_registrant.cc b/example/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..2e68889 --- /dev/null +++ b/example/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,27 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include +#include +#include +#include + +void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin"); + audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar); + g_autoptr(FlPluginRegistrar) desktop_drop_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopDropPlugin"); + desktop_drop_plugin_register_with_registrar(desktop_drop_registrar); + g_autoptr(FlPluginRegistrar) pasteboard_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin"); + pasteboard_plugin_register_with_registrar(pasteboard_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); +} diff --git a/example/linux/flutter/generated_plugin_registrant.h b/example/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..e0f0a47 --- /dev/null +++ b/example/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/example/linux/flutter/generated_plugins.cmake b/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000..fa2eba0 --- /dev/null +++ b/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,27 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + audioplayers_linux + desktop_drop + pasteboard + url_launcher_linux +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/example/linux/main.cc b/example/linux/main.cc new file mode 100644 index 0000000..e7c5c54 --- /dev/null +++ b/example/linux/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/example/linux/my_application.cc b/example/linux/my_application.cc new file mode 100644 index 0000000..0ba8f43 --- /dev/null +++ b/example/linux/my_application.cc @@ -0,0 +1,104 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "example"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "example"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/example/linux/my_application.h b/example/linux/my_application.h new file mode 100644 index 0000000..72271d5 --- /dev/null +++ b/example/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/example/macos/.gitignore b/example/macos/.gitignore new file mode 100644 index 0000000..746adbb --- /dev/null +++ b/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/example/macos/Flutter/Flutter-Debug.xcconfig b/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..4b81f9b --- /dev/null +++ b/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Flutter/Flutter-Release.xcconfig b/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..5caa9d1 --- /dev/null +++ b/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..e63f903 --- /dev/null +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,34 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import audioplayers_darwin +import desktop_drop +import device_info_plus_macos +import fc_native_video_thumbnail_for_us +import package_info_plus_macos +import pasteboard +import path_provider_foundation +import photo_manager +import shared_preferences_foundation +import sqflite +import url_launcher_macos +import wakelock_macos + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin")) + DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FcNativeVideoThumbnailPlugin.register(with: registry.registrar(forPlugin: "FcNativeVideoThumbnailPlugin")) + FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) + PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + PhotoManagerPlugin.register(with: registry.registrar(forPlugin: "PhotoManagerPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) +} diff --git a/example/macos/Podfile b/example/macos/Podfile new file mode 100644 index 0000000..9ec46f8 --- /dev/null +++ b/example/macos/Podfile @@ -0,0 +1,40 @@ +platform :osx, '10.15' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock new file mode 100644 index 0000000..4b372e6 --- /dev/null +++ b/example/macos/Podfile.lock @@ -0,0 +1,68 @@ +PODS: + - FlutterMacOS (1.0.0) + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - package_info_plus_macos (0.0.1): + - FlutterMacOS + - path_provider_macos (0.0.1): + - FlutterMacOS + - photo_manager (2.0.0): + - Flutter + - FlutterMacOS + - shared_preferences_macos (0.0.1): + - FlutterMacOS + - sqflite (0.0.2): + - FlutterMacOS + - FMDB (>= 2.7.5) + - url_launcher_macos (0.0.1): + - FlutterMacOS + - wakelock_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - package_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos`) + - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) + - photo_manager (from `Flutter/ephemeral/.symlinks/plugins/photo_manager/macos`) + - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) + - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + - wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`) + +SPEC REPOS: + trunk: + - FMDB + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + package_info_plus_macos: + :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos + path_provider_macos: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos + photo_manager: + :path: Flutter/ephemeral/.symlinks/plugins/photo_manager/macos + shared_preferences_macos: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos + sqflite: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + wakelock_macos: + :path: Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos + +SPEC CHECKSUMS: + FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811 + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + package_info_plus_macos: f010621b07802a241d96d01876d6705f15e77c1c + path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19 + photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604 + shared_preferences_macos: a64dc611287ed6cbe28fd1297898db1336975727 + sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea + url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3 + wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 + +PODFILE CHECKSUM: 0d3963a09fc94f580682bd88480486da345dc3f0 + +COCOAPODS: 1.11.3 diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1dad809 --- /dev/null +++ b/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,632 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + BCA39B6D459F9CBDE3F985BB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6AB45B5BD0777F55845AF08A /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 5E1960EFBF841FBF2ED9CB42 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 613D89C488B7E8A9AABFE80A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 6AB45B5BD0777F55845AF08A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9055C8A896F8B9969E9A9A75 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BCA39B6D459F9CBDE3F985BB /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 35CB9EEBE37DA168A0AC063E /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + 35CB9EEBE37DA168A0AC063E /* Pods */ = { + isa = PBXGroup; + children = ( + 613D89C488B7E8A9AABFE80A /* Pods-Runner.debug.xcconfig */, + 9055C8A896F8B9969E9A9A75 /* Pods-Runner.release.xcconfig */, + 5E1960EFBF841FBF2ED9CB42 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6AB45B5BD0777F55845AF08A /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + DF30845ABEF3338382F8E5CB /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 2F97E070B313FE8332FEB41C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 2F97E070B313FE8332FEB41C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + DF30845ABEF3338382F8E5CB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..fb7259e --- /dev/null +++ b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/macos/Runner/AppDelegate.swift b/example/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..d53ef64 --- /dev/null +++ b/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..82b6f9d9a33e198f5747104729e1fcef999772a5 GIT binary patch literal 102994 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ⅅ8MglG&ER{i5lN315cO?EdHNLrg? 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 z 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 Pe7HEdAEg|=c=LY&YVNkY literal 0 HcmV?d00001 diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..13b35eba55c6dabc3aac36f33d859266c18fa0d0 GIT binary patch literal 5680 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 literal 0 HcmV?d00001 diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000000000000000000000000000000000000..0a3f5fa40fb3d1e0710331a48de5d256da3f275d GIT binary patch literal 520 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 literal 0 HcmV?d00001 diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1632cfddf3d9dade342351e627a0a75609fb46 GIT binary patch literal 2218 zcmV;b2vzrqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuE6iGxuRCodHTWf3-RTMruyW6Fu zQYeUM04eX6D5c0FCjKKPrco1(K`<0SL=crI{PC3-^hZU0kQie$gh-5!7z6SH6Q0J% zqot*`H1q{R5fHFYS}dje@;kG=v$L0(yY0?wY2%*c?A&{2?!D*x?m71{of2gv!$5|C z3>qG_BW}7K_yUcT3A5C6QD<+{aq?x;MAUyAiJn#Jv8_zZtQ{P zTRzbL3U9!qVuZzS$xKU10KiW~Bgdcv1-!uAhQxf3a7q+dU6lj?yoO4Lq4TUN4}h{N z*fIM=SS8|C2$(T>w$`t@3Tka!(r!7W`x z-isCVgQD^mG-MJ;XtJuK3V{Vy72GQ83KRWsHU?e*wrhKk=ApIYeDqLi;JI1e zuvv}5^Dc=k7F7?nm3nIw$NVmU-+R>> zyqOR$-2SDpJ}Pt;^RkJytDVXNTsu|mI1`~G7yw`EJR?VkGfNdqK9^^8P`JdtTV&tX4CNcV4 z&N06nZa??Fw1AgQOUSE2AmPE@WO(Fvo`%m`cDgiv(fAeRA%3AGXUbsGw{7Q`cY;1BI#ac3iN$$Hw z0LT0;xc%=q)me?Y*$xI@GRAw?+}>=9D+KTk??-HJ4=A>`V&vKFS75@MKdSF1JTq{S zc1!^8?YA|t+uKigaq!sT;Z!&0F2=k7F0PIU;F$leJLaw2UI6FL^w}OG&!;+b%ya1c z1n+6-inU<0VM-Y_s5iTElq)ThyF?StVcebpGI znw#+zLx2@ah{$_2jn+@}(zJZ{+}_N9BM;z)0yr|gF-4=Iyu@hI*Lk=-A8f#bAzc9f z`Kd6K--x@t04swJVC3JK1cHY-Hq+=|PN-VO;?^_C#;coU6TDP7Bt`;{JTG;!+jj(` zw5cLQ-(Cz-Tlb`A^w7|R56Ce;Wmr0)$KWOUZ6ai0PhzPeHwdl0H(etP zUV`va_i0s-4#DkNM8lUlqI7>YQLf)(lz9Q3Uw`)nc(z3{m5ZE77Ul$V%m)E}3&8L0 z-XaU|eB~Is08eORPk;=<>!1w)Kf}FOVS2l&9~A+@R#koFJ$Czd%Y(ENTV&A~U(IPI z;UY+gf+&6ioZ=roly<0Yst8ck>(M=S?B-ys3mLdM&)ex!hbt+ol|T6CTS+Sc0jv(& z7ijdvFwBq;0a{%3GGwkDKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U z@~$z0V`OVtIbEx5pa|Tct|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-M2 z@O~lQ0OiKQp}o9I;?uxCgYVV?FH|?Riri*U$Zi_`V2eiA>l zdSm6;SEm6#T+SpcE8Ro_f2AwxzI z44hfe^WE3!h@W3RDyA_H440cpmYkv*)6m1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYr + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/macos/Runner/Configs/AppInfo.xcconfig b/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..8b42559 --- /dev/null +++ b/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.example + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. diff --git a/example/macos/Runner/Configs/Debug.xcconfig b/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/example/macos/Runner/Configs/Release.xcconfig b/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/example/macos/Runner/Configs/Warnings.xcconfig b/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/example/macos/Runner/DebugProfile.entitlements b/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..9f56413 --- /dev/null +++ b/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/example/macos/Runner/Info.plist b/example/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/example/macos/Runner/MainFlutterWindow.swift b/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..2722837 --- /dev/null +++ b/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/example/macos/Runner/Release.entitlements b/example/macos/Runner/Release.entitlements new file mode 100644 index 0000000..f7eba17 --- /dev/null +++ b/example/macos/Runner/Release.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/example/pubspec.lock b/example/pubspec.lock index 8f6a22c..0b1b6c2 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "569ddca58d535e601dd1584afa117710abc999d036c0cd2c51777fb257df78e8" + sha256: "0c80aeab9bc807ab10022cd3b2f4cf2ecdf231949dc1ddd9442406a003f19201" url: "https://pub.dev" source: hosted - version: "53.0.0" + version: "52.0.0" adaptive_action_sheet: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: analyzer - sha256: "10927c4b7c7c88b1adbca278c3d5531db92e2f4b4abf04e2919a800af965f3f5" + sha256: cd8ee83568a77f3ae6b913a36093a1c9b1264e7cb7f834d9ddd2311dade9c1f4 url: "https://pub.dev" source: hosted - version: "5.5.0" + version: "5.4.0" archive: dependency: "direct main" description: @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: args - sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.3.2" async: dependency: transitive description: @@ -49,14 +49,70 @@ packages: url: "https://pub.dev" source: hosted version: "2.10.0" - azlistview: + audioplayers: dependency: transitive description: - name: azlistview - sha256: "93e865f11777a271b439f0d6b00799c0797e9daeec2e082a2e01373809c4b90d" + name: audioplayers + sha256: "16451eab798b23ad9307aef6f9ca62bb8fb06542af8810eead0d236d3fd40a42" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + audioplayers_android: + dependency: transitive + description: + name: audioplayers_android + sha256: b2c833e6f718b6b030454e329931229afafe9327fdb002874dd544dc8bf2484d url: "https://pub.dev" source: hosted version: "2.0.0" + audioplayers_darwin: + dependency: transitive + description: + name: audioplayers_darwin + sha256: e7a3c8759bf11ecfe4b20df338bf9f3d37c7719a5761c46a3833aba0ceeaacff + url: "https://pub.dev" + source: hosted + version: "3.0.1" + audioplayers_linux: + dependency: transitive + description: + name: audioplayers_linux + sha256: e95b65e1f4d4764601dac5e65f8d8186fc29401043ab020f1dacec483d708707 + url: "https://pub.dev" + source: hosted + version: "1.0.4" + audioplayers_platform_interface: + dependency: transitive + description: + name: audioplayers_platform_interface + sha256: "178581a44cb685fd798d2108111d2e98cca3400e30b9c3a05546f124fb37f600" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + audioplayers_web: + dependency: transitive + description: + name: audioplayers_web + sha256: "859ba09be2a57e57a787273f18c8cf0d9b61383870c5ee4b5632fe9adbc37edf" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + audioplayers_windows: + dependency: transitive + description: + name: audioplayers_windows + sha256: "622e01c4c357c2aaf1b956c3a0f89d97c3cb40315c03f16e3b6c2a31ff9c38bc" + url: "https://pub.dev" + source: hosted + version: "1.1.3" + azlistview_all_platforms: + dependency: transitive + description: + name: azlistview_all_platforms + sha256: "47ce2204863e0c3e481ca2a3813096d9818b153f1f677e839503e33d36e97993" + url: "https://pub.dev" + source: hosted + version: "2.1.2" boolean_selector: dependency: transitive description: @@ -109,10 +165,10 @@ packages: dependency: transitive description: name: camera_android - sha256: e491c836147f60dd8a54cf3895fd2960e13b21b78a9d15b563a1b6c70894f142 + sha256: "4cef01e8e78fe27c809a429bf74352ab94ab76b0c980e3ec708f1414614e3d9f" url: "https://pub.dev" source: hosted - version: "0.10.4" + version: "0.10.3" camera_avfoundation: dependency: transitive description: @@ -125,10 +181,10 @@ packages: dependency: transitive description: name: camera_platform_interface - sha256: b632be28e61d00a233f67d98ea90fd7041956f27a1c65500188ee459be60e15f + sha256: "0eedd642d905ca24f1c483fe9ea0d0e7287b86a402845c28d24df28cc7b0ee6e" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.3.4" camera_web: dependency: transitive description: @@ -225,6 +281,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + desktop_drop: + dependency: transitive + description: + name: desktop_drop + sha256: "4ca4d960f4b11c032e9adfd2a0a8ac615bc3fddb4cbe73dcf840dd8077582186" + url: "https://pub.dev" + source: hosted + version: "0.4.1" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: b809c4ed5f7fcdb325ccc70b80ad934677dc4e2aa414bf46859a42bfdfafcbb6 + url: "https://pub.dev" + source: hosted + version: "4.1.3" + device_info_plus_linux: + dependency: transitive + description: + name: device_info_plus_linux + sha256: "77a8b3c4af06bc46507f89304d9f49dfc64b4ae004b994532ed23b34adeae4b3" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_macos: + dependency: transitive + description: + name: device_info_plus_macos + sha256: "37961762fbd46d3620c7b69ca606671014db55fc1b7a11e696fd90ed2e8fe03d" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: "83fdba24fcf6846d3b10f10dfdc8b6c6d7ada5f8ed21d62ea2909c2dfa043773" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_web: + dependency: transitive + description: + name: device_info_plus_web + sha256: "5890f6094df108181c7a29720bc23d0fd6159f17d82787fac093d1fefcaf6325" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_windows: + dependency: transitive + description: + name: device_info_plus_windows + sha256: "23a2874af0e23ee6e3a2a0ebcecec3a9da13241f2cb93a93a44c8764df123dd7" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + diff_match_patch: + dependency: transitive + description: + name: diff_match_patch + sha256: "2efc9e6e8f449d0abe15be240e2c2a3bcd977c8d126cfd70598aee60af35c0a4" + url: "https://pub.dev" + source: hosted + version: "0.4.1" disk_space: dependency: transitive description: @@ -245,10 +365,10 @@ packages: dependency: transitive description: name: extended_image - sha256: a6b738d9b8d5513be72c545cc3e9c5c451fbee77c8db3cbec7c32ae85b82fb93 + sha256: "5854d0d05ee0c687d1852af9db05f15cfe058520fa56f417075705c5bce965d4" url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.4.0" extended_image_library: dependency: transitive description: @@ -273,14 +393,22 @@ packages: url: "https://pub.dev" source: hosted version: "5.12.6" + fc_native_video_thumbnail_for_us: + dependency: transitive + description: + name: fc_native_video_thumbnail_for_us + sha256: db6fa2998195ef5eadac690ae58d6a909ddb5b0283ebbbf9ae4e0e8f99a54902 + url: "https://pub.dev" + source: hosted + version: "0.4.8+1" ffi: dependency: transitive description: name: ffi - sha256: "13a6ccf6a459a125b3fcdb6ec73bd5ff90822e071207c663bfd1f70062d51d18" + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "2.0.1" file: dependency: transitive description: @@ -293,10 +421,10 @@ packages: dependency: transitive description: name: file_picker - sha256: "704259669b5e9cb24e15c11cfcf02caf5f20d30901b3916d60b6d1c2d647035f" + sha256: b85eb92b175767fdaa0c543bf3b0d1f610fe966412ea72845fe5ba7801e763ff url: "https://pub.dev" source: hosted - version: "4.6.1" + version: "5.2.10" file_utils: dependency: transitive description: @@ -350,19 +478,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" - flutter_localizations: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" flutter_markdown: dependency: transitive description: name: flutter_markdown - sha256: "7b25c10de1fea883f3c4f9b8389506b54053cd00807beab69fd65c8653a2711f" + sha256: "818cf6c28377ba2c91ed283c96fd712e9c175dd2d2488eb7fc93b6afb9ad2e08" url: "https://pub.dev" source: hosted - version: "0.6.14" + version: "0.6.13+1" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -387,14 +510,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - flutter_spinkit: - dependency: transitive - description: - name: flutter_spinkit - sha256: "77a2117c0517ff909221f3160b8eb20052ab5216107581168af574ac1f05dff8" - url: "https://pub.dev" - source: hosted - version: "5.1.0" flutter_svg: dependency: transitive description: @@ -481,18 +596,18 @@ packages: dependency: transitive description: name: image_picker - sha256: d39cc12402dab8365fe5b5370e64694ae0223d675c36b15ff0490b7cc3d32551 + sha256: f98d76672d309c8b7030c323b3394669e122d52b307d2bbd8d06bd70f5b2aabe url: "https://pub.dev" source: hosted - version: "0.8.6+2" + version: "0.8.6+1" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "385f12ee9c7288575572c7873a332016ec45ebd092e1c2f6bd421b4a9ad21f1d" + sha256: b1cbfec0f5aef427a18eb573f5445af8c9c568626bf3388553e40c263d3f7368 url: "https://pub.dev" source: hosted - version: "0.8.5+6" + version: "0.8.5+5" image_picker_for_web: dependency: transitive description: @@ -505,10 +620,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: "884ed71165bc01ffe1b0b7813e6fa17e1e9442da974656f99b79a292371303d6" + sha256: "39c013200046d14c58b71dc4fa3d00e425fc9c699d589136cd3ca018727c0493" url: "https://pub.dev" source: hosted - version: "0.8.6+8" + version: "0.8.6+6" image_picker_platform_interface: dependency: transitive description: @@ -585,10 +700,10 @@ packages: dependency: transitive description: name: markdown - sha256: b3c60dee8c2af50ad0e6e90cceba98e47718a6ee0a7a6772c77846a0cc21f78b + sha256: c2b81e184067b41d0264d514f7cdaa2c02d38511e39d6521a1ccc238f6d7b3f2 url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "6.0.1" matcher: dependency: transitive description: @@ -649,10 +764,10 @@ packages: dependency: transitive description: name: package_info_plus - sha256: "7a6114becdf042be2b0777d77ace954d4a205644171a1cbd8712976b9bbb837c" + sha256: f62d7253edc197fe3c88d7c2ddab82d68f555e778d55390ccc3537eca8e8d637 url: "https://pub.dev" source: hosted - version: "1.4.2" + version: "1.4.3+1" package_info_plus_linux: dependency: transitive description: @@ -689,10 +804,18 @@ packages: dependency: transitive description: name: package_info_plus_windows - sha256: a6040b8695c82f8dd3c3d4dfab7ef96fbe9c67aac21b9bcf5db272589ef84441 + sha256: "79524f11c42dd9078b96d797b3cf79c0a2883a50c4920dc43da8562c115089bc" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "2.1.0" + pasteboard: + dependency: transitive + description: + name: pasteboard + sha256: "1c8b6a8b3f1d12e55d4e9404433cda1b4abe66db6b17bc2d2fb5965772c04674" + url: "https://pub.dev" + source: hosted + version: "0.2.0" path: dependency: transitive description: @@ -745,10 +868,10 @@ packages: dependency: transitive description: name: path_provider_linux - sha256: "2e32f1640f07caef0d3cb993680f181c79e54a3827b997d5ee221490d131fbd9" + sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 url: "https://pub.dev" source: hosted - version: "2.1.8" + version: "2.1.7" path_provider_platform_interface: dependency: transitive description: @@ -761,10 +884,10 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905 + sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6 url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.1.6" pedantic: dependency: transitive description: @@ -829,14 +952,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.5.2" - photo_view: - dependency: transitive - description: - name: photo_view - sha256: "8036802a00bae2a78fc197af8a158e3e2f7b500561ed23b4c458107685e645bb" - url: "https://pub.dev" - source: hosted - version: "0.14.0" platform: dependency: transitive description: @@ -909,14 +1024,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" - scrollable_positioned_list: + scrollable_positioned_list_for_us: dependency: transitive description: - name: scrollable_positioned_list - sha256: "9566352ab9ba05794ee6c8864f154afba5d36c5637d0e3e32c615ba4ceb92772" + name: scrollable_positioned_list_for_us + sha256: b5bcbb35114902c004a4f98f2dbd5b0a5a7f80a0144a8b46297601e38fa5383d url: "https://pub.dev" source: hosted - version: "0.2.3" + version: "0.4.2" shared_preferences: dependency: transitive description: @@ -1062,33 +1177,41 @@ packages: dependency: transitive description: name: tencent_cloud_chat_sdk - sha256: "32b7e40c5a1682b3ee85daa73504af3d0d4e60a93472b279591e769b15b4861c" + sha256: "765a93262a41080e155ce5b8a6ca20147a81c7d306f7f87444077c5eaae87e08" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.1.5" tencent_cloud_chat_uikit: dependency: "direct main" description: path: ".." relative: true source: path - version: "1.7.0" + version: "2.0.0+1" + tencent_cloud_uikit_core: + dependency: transitive + description: + name: tencent_cloud_uikit_core + sha256: "829dfde0c4fbdae019ba233f7f2c299e7cbd18c3ae20ecfe3ab4a43084a33064" + url: "https://pub.dev" + source: hosted + version: "1.0.2" tencent_extended_text: dependency: transitive description: name: tencent_extended_text - sha256: cf0d283c01a9e63f75666d8b5b1cabd463e18e51802bf1d093d7a65bd369b3d4 + sha256: "27a2f7ee58ada480e295102471f1733a7402178a239d0c80a7aa33a134c641ef" url: "https://pub.dev" source: hosted - version: "1.0.2+1" + version: "1.0.2" tencent_extended_text_field: dependency: transitive description: name: tencent_extended_text_field - sha256: daa10f3775bfac1cc841b34275c2746ced7764f3b77222a93edb4c13bad1209b + sha256: d311c240983dbf78e31b58f91e425920a40d6564942813e692a3419bf5c9deb0 url: "https://pub.dev" source: hosted - version: "1.0.1+2" + version: "1.0.1" tencent_extended_text_library: dependency: transitive description: @@ -1101,26 +1224,34 @@ packages: dependency: transitive description: name: tencent_im_base - sha256: b5917ff0bae7c31d52f54932349fc400d3752719a1c5a2f0209258f85c7a6c07 + sha256: "516356a80f43b94a6c0719b54e4c641cb1f164830b2b3e887d175ae862ebab3f" url: "https://pub.dev" source: hosted - version: "1.0.26" + version: "1.0.51" + tencent_im_sdk_plugin_desktop: + dependency: "direct main" + description: + name: tencent_im_sdk_plugin_desktop + sha256: "5fe5ab0765183185fe4a1f94ce1fdc6ab0a450b8522011806549678edb52130d" + url: "https://pub.dev" + source: hosted + version: "0.1.13" tencent_im_sdk_plugin_platform_interface: dependency: transitive description: name: tencent_im_sdk_plugin_platform_interface - sha256: "7aff6a8495eae3efc3aed1ed944bab7a0ce7eb1035d09b3f3d7974bcb3d8b137" + sha256: "04043582f1af698b4abe12d53cd0f043466228fae712677688988d8ff7bfc1f1" url: "https://pub.dev" source: hosted - version: "0.3.12" + version: "0.3.19" tencent_im_sdk_plugin_web: dependency: "direct main" description: name: tencent_im_sdk_plugin_web - sha256: d83a2370398948bccdc3fa4aae33840bcee62d78faa288823a02d9e0e4ab677f + sha256: "6ddf543c6fb4a2c220c5cec3b9247b4353c3dc0f276e76b81c800ad4c92f9bb5" url: "https://pub.dev" source: hosted - version: "0.3.7" + version: "0.3.9" tencent_keyboard_visibility: dependency: transitive description: @@ -1133,10 +1264,10 @@ packages: dependency: transitive description: name: tencent_open_file - sha256: "98cbffe55e3245a308fbf76e18c9a0f808e534c624bc1a1cc0a00bd63a418290" + sha256: "01f94f618da42e5593bbad0657fcd13cfc1c2360cca805d8cdfefe898cbe5429" url: "https://pub.dev" source: hosted - version: "4.0.9+1" + version: "4.0.10" tencent_super_tooltip: dependency: transitive description: @@ -1149,10 +1280,10 @@ packages: dependency: transitive description: name: tencent_wechat_camera_picker - sha256: "6a6fd12d61ad2ef17273a226a165fe0b5e3ef5c7e49779de38503e4f4b6e3ef1" + sha256: "8f95b435c7a12a9221f00fe4354fb9c0f9313d79cc09ddb5902b7b418185092d" url: "https://pub.dev" source: hosted - version: "3.6.5+2" + version: "3.6.5+1" term_glyph: dependency: transitive description: @@ -1173,18 +1304,18 @@ packages: dependency: transitive description: name: tim_ui_kit_sticker_plugin - sha256: cd5d6e2380deaf73e420602bbfe3da36c0f3253adc531f76e139efec80671175 + sha256: "2a825d33076f319f6c1c87d58e2b0d650c9284ae4afd8efdc206f3e6f3582e64" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "2.0.1" transparent_image: dependency: transitive description: name: transparent_image - sha256: e8991d955a2094e197ca24c645efec2faf4285772a4746126ca12875e54ca02f + sha256: e566a616922a781489f4d91cc939b1b3203b6e4a093317805f2f82f0bb0f8dec url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.0" tuple: dependency: transitive description: @@ -1205,26 +1336,26 @@ packages: dependency: transitive description: name: universal_html - sha256: b5061c64c7c863c12e46279e032976f1c274f927fb3589b52b5928dcd2d52f7c + sha256: "5ff50b7c14d201421cf5230ec389a0591c4deb5c817c9d7ccca3b26fe5f31e34" url: "https://pub.dev" source: hosted - version: "2.0.9" + version: "2.0.8" universal_io: dependency: transitive description: name: universal_io - sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d" + sha256: "79f78ddad839ee3aae3ec7c01eb4575faf0d5c860f8e5223bc9f9c17f7f03cef" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.0.4" url_launcher: dependency: transitive description: name: url_launcher - sha256: e8f2efc804810c0f2f5b485f49e7942179f56eabcfe81dce3387fec4bb55876b + sha256: "698fa0b4392effdc73e9e184403b627362eb5fbf904483ac9defbb1c2191d809" url: "https://pub.dev" source: hosted - version: "6.1.9" + version: "6.1.8" url_launcher_android: dependency: transitive description: @@ -1237,10 +1368,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: "0a5af0aefdd8cf820dd739886efb1637f1f24489900204f50984634c07a54815" + sha256: bb328b24d3bccc20bdf1024a0990ac4f869d57663660de9c936fb8c043edefe3 url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.0.18" url_launcher_linux: dependency: transitive description: @@ -1337,14 +1468,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.13" - video_thumbnail: - dependency: transitive - description: - name: video_thumbnail - sha256: "3455c189d3f0bb4e3fc2236475aa84fe598b9b2d0e08f43b9761f5bc44210016" - url: "https://pub.dev" - source: hosted - version: "0.5.3" wakelock: dependency: transitive description: @@ -1381,10 +1504,10 @@ packages: dependency: transitive description: name: wakelock_windows - sha256: "108b1b73711f1664ee462e73af34a9286ff496e27d4d8371e2fb4da8fde4cdac" + sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.1" watcher: dependency: transitive description: @@ -1405,18 +1528,18 @@ packages: dependency: transitive description: name: win32 - sha256: c0e3a4f7be7dae51d8f152230b86627e3397c1ba8c3fa58e63d44a9f3edc9cef + sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4 url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "3.1.4" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "0.2.0+3" xml: dependency: transitive description: @@ -1434,5 +1557,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.19.0 <4.0.0" + dart: ">=2.19.0 <3.0.0" flutter: ">=3.7.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 4eecb12..f19a45a 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -36,8 +36,17 @@ dependencies: cupertino_icons: ^1.0.2 tencent_cloud_chat_uikit: path: ../../tim_ui_kit - tencent_im_sdk_plugin_web: ^0.3.2 + tencent_im_sdk_plugin_web: ^0.3.9 archive: ^3.3.0 + tencent_im_sdk_plugin_desktop: ^0.1.13 + +# dependency_overrides: +# tencent_cloud_chat_sdk: +# path: /Users/wangrunlin/Documents/GitHub/im-flutter-plugin/tencent_im_sdk_plugin +# tencent_im_sdk_plugin_desktop: +# path: /Users/wangrunlin/Documents/GitHub/im-flutter-plugin/tencent_im_sdk_plugin_desktop +# tencent_im_sdk_plugin_web: +# path: /Users/wangrunlin/Documents/GitHub/im-flutter-plugin/tencent_im_sdk_plugin_web dev_dependencies: flutter_test: diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index a0d0bbe..03ccc3e 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -6,10 +6,22 @@ #include "generated_plugin_registrant.h" +#include +#include +#include +#include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + AudioplayersWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin")); + DesktopDropPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("DesktopDropPlugin")); + FcNativeVideoThumbnailForUsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FcNativeVideoThumbnailForUsPluginCApi")); + PasteboardPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PasteboardPlugin")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/example/windows/flutter/generated_plugins.cmake b/example/windows/flutter/generated_plugins.cmake index c20a586..ad68f93 100644 --- a/example/windows/flutter/generated_plugins.cmake +++ b/example/windows/flutter/generated_plugins.cmake @@ -3,6 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST + audioplayers_windows + desktop_drop + fc_native_video_thumbnail_for_us + pasteboard permission_handler_windows url_launcher_windows ) diff --git a/images/folder_open.png b/images/folder_open.png new file mode 100644 index 0000000000000000000000000000000000000000..9557b37a6dbb5b31198e12ec283e703717a2a921 GIT binary patch literal 440 zcmV;p0Z0CcP)Px$a!Eu%RA@u(m|YTrFbssl&GcmI$@FGA>kLek7V^_T(DsEF(&Wo7ZRtP%Qtd& zSg)o!8i6shWdr~cML=NQGZ8&FWfVXZ1d0d5G$H}Ki-0J;1Blub_>x5dzDfm_CYpNC z0<_xXMAfal^xk9s4uG%kvo*OzTNmcQxeWQo@ov6W0q-vDVdVCm_5%$-aRN_8%2=L% zI%8P@!VhT$IIg}4Af5lU-#|M5YXDOE-wKe%{~CZj{f|1U_LZ(eDg7^1Ag%u`0DJr2 z^h?R@v-SCB(f?8f()wQl0LzS*T(ci)HJ>`n9{y@eZ=ZEwu*%3kSOYahrB-E0000Px$FiAu~RA@u(nOP3PFboCVlL03KP6jsvS)wSak~odmg7Z@ek#xq-fi4Rid@Kj& zhZOKmFcXNLz!?Cp0D#AtQ6~JFS)iCx?Ur5(-9GS~^STN=7?oe8T?NX>EjN2B`Q0t# zA<%2v@B&--`(_V@7O27FXJi-jdYhcg`FSelw&3wAB!jm=4?esA1s_^q1U{_5D11nP zJ@DZK_QHn}n1K%?Fbf|-fCE4DKdJdgrVfvWS^_5US^|>r=GQ`!@aCIX8s1bu1Kv#l z@1#&jVwmoM6TDtJQvYfKZ!+_2 UG31ryw*UYD07*qoM6N<$f&?y?5dZ)H literal 0 HcmV?d00001 diff --git a/images/video_icon.png b/images/video_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..adeacddff6541412810214d9daabd2665e83cd97 GIT binary patch literal 1502 zcmX}sdoGh-wnk5p5L)ld?pEsM%7wRz-S z-j$7Xa13eXkR7k4ykGMDsb#&7m#&+eY{x!?P}_x^Y9IX466joz)Ks|16=b^{(L zKWGl!9te3TN8RsjAHd`N(5|qCfqfjP_u)JVZqOzSCQD6~5s8p*INS<0a1}%1df}N^ z5*tHY#1fboKPEtAV~K2lz`+t&7=IQ9N&*Y&+sl8k|11CRY!{hK20}pD7Gz5%g-B%* zh(xw20mYl3SPY6ppil@3AOdhh0IqL<>+2wYeT&ZrS9x2jt6Pg)DT5_pFr^HpWOiOM zJ-azEwK+byN&hMy8Wj(Xh-t%O+K_l)P}KjI=>4C<&JV)QZee?;prvi&b<;+51OIs~ zzp{p3QOz%Z!7qEUR#LfET(Op4!pkq_Juc+s74p(ES5oeNOG;f%ytPb8S&mCuioUjV zDUN&bD)+)wZd436;>uzec`@|DV#tNXv*$TMk(@IToWO8Sz&Vb8DBC}T;~&B%hOi02 zY`-A3PXNn1faL`xiRA_HXL&-1EG&_Qf%2al1Mn;lh#w2>%X0T+qH!#D9McWr!$d*6 znWrFLOjn2}(*=TMI%6OVCk)dGN`UDEFdPAf1H^-2k7iiR$N4~yY4DSuHy#F;lUGyM zFfp?@>fq>l<7P?eAI)te^w|Z0Xj3BH0vjLRJq&}%=K&}eLgLu+*m$&_+rA#&v{YtI z?g5710J=@p1{YCj&3=06fi12R)H4Bbbq6e+?cqLydg?Vro5xz_citutG9Ke{4xZS#Dk5O-b2@opKSw z;Ur~c_S>#5%Baa{q~+fB;2`JePuhIp8zk!EgxSK3OGE5I`7p{t?f8krW49z@lO`^m zom#tg3}hw8Dn1M9ayVtxfrvr!f0aWd9#mJC>^`c|xN4$Y1`FOXM;5v5RoI#45~^;O z+YMI`t}5E5@b~(7 zIy?=jV5nMe-l={9VV7xFCwjt6vk8{Z(NWIoNL4hwr%yn8Ek)4)C5<_Q`tY8VsT8|} za}5I-^122?Umlh|W$2U2W_mg0qZRPRs2+0d?u-ZNu{M)IV~OsX_YEFdI15J5FV>6J zlmIeM>0Zg&cyWc1o-@^0Ri%<7nh^6gdMb?CE(x{Gv=VFwPwEuRu|%Tv_f6XS=MQOY zI1VbnF?rU-At^p&x0m(bDcTl#o44EC_$K;{1hPek=E583j`po>U~b(@ho_@>es7-e z2eEj^6(ufStI4WB)?ZyV?wtPB6dP&v?B|bPw3_rkkEwmdQtyVJqBPsIw?D66Uz+^1 z3+G-w4UbAg3^P{fHJTbUAq<~s+U-*?USU+S0?%~k7d`1qNT&nj8>%$H5UA%}5N� znL4L7lS+vac`|Yqs^}Re#Lx{8P38C;QE~GNgc&6{qYVY~&e`+DXOrlcOylv>C=00&(+e5Ni6Y_*i+m>com2<>C*a42Xc8I}U e%Ua<&-I7l-PH4Y!)swRQH3M$ms0P>2+kXQ&xDB@e literal 0 HcmV?d00001 diff --git a/lib/base_widgets/tim_ui_kit_state.dart b/lib/base_widgets/tim_ui_kit_state.dart index d39284c..4ac9978 100644 --- a/lib/base_widgets/tim_ui_kit_state.dart +++ b/lib/base_widgets/tim_ui_kit_state.dart @@ -8,10 +8,6 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; class TIMUIKitState extends TIMState { final CoreServicesImpl _coreServices = serviceLocator(); - @override - initState() { - super.initState(); - } @override void onTIMCallback(TIMCallback callbackValue) { diff --git a/lib/business_logic/separate_models/tui_chat_model_tools.dart b/lib/business_logic/separate_models/tui_chat_model_tools.dart index eee084c..521923e 100644 --- a/lib/business_logic/separate_models/tui_chat_model_tools.dart +++ b/lib/business_logic/separate_models/tui_chat_model_tools.dart @@ -1,13 +1,11 @@ import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/core/core_services_implements.dart'; -import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; class TUIChatModelTools { final TUIChatGlobalModel globalModel = serviceLocator(); final CoreServicesImpl _coreServices = serviceLocator(); - final MessageService _messageService = serviceLocator(); OfflinePushInfo buildMessagePushInfo( V2TimMessage message, String convID, ConvType convType) { @@ -15,6 +13,14 @@ class TUIChatModelTools { return "{\"conversationID\": \"$convID\"}"; } + if (globalModel.chatConfig.offlinePushInfo != null) { + final customData = + globalModel.chatConfig.offlinePushInfo!(message, convID, convType); + if(customData != null){ + return customData; + } + } + String title = globalModel.chatConfig.notificationTitle; // If user provides null, use default ext. @@ -109,35 +115,9 @@ class TUIChatModelTools { }); if (targetIndex != null && - targetIndex != -1 && + targetIndex > -1 && currentHistoryMsgList.isNotEmpty) { - List response; - if (currentHistoryMsgList.length > targetIndex + 2) { - response = await _messageService.getHistoryMessageList( - count: 1, - getType: HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_NEWER_MSG, - userID: conversationType == ConvType.c2c ? conversationID : null, - groupID: conversationType == ConvType.group ? conversationID : null, - lastMsgID: currentHistoryMsgList[targetIndex + 1].msgID); - } else { - response = await _messageService.getHistoryMessageList( - count: 5, - getType: HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG, - userID: conversationType == ConvType.c2c ? conversationID : null, - groupID: conversationType == ConvType.group ? conversationID : null, - lastMsgID: currentHistoryMsgList.length - 3 < 0 - ? null - : currentHistoryMsgList[currentHistoryMsgList.length - 3].msgID, - ); - } - - try { - return response.firstWhere((item) { - return item.msgID == msgID; - }); - } catch (e) { - return null; - } + return currentHistoryMsgList[targetIndex]; } else { return null; } diff --git a/lib/business_logic/separate_models/tui_chat_separate_view_model.dart b/lib/business_logic/separate_models/tui_chat_separate_view_model.dart index 9584351..a342a4a 100644 --- a/lib/business_logic/separate_models/tui_chat_separate_view_model.dart +++ b/lib/business_logic/separate_models/tui_chat_separate_view_model.dart @@ -2,10 +2,14 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:math'; + import 'package:flutter/cupertino.dart'; + +// ignore: unnecessary_import +import 'package:flutter/foundation.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/chat_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_model_tools.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; @@ -17,10 +21,7 @@ import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.d import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:uuid/uuid.dart'; -enum LoadDirection { - previous, - latest -} +enum LoadDirection { previous, latest } class TUIChatSeparateViewModel extends ChangeNotifier { final FriendshipServices _friendshipServices = @@ -39,7 +40,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier { ConvType? conversationType; bool haveMoreData = false; bool haveMoreLatestData = false; - String _currentSelectedMsgId = ""; + String _currentPlayedMsgId = ""; String _editRevokedMsg = ""; GroupReceiptAllowType? _groupType; List _multiSelectedMessageList = []; @@ -51,11 +52,29 @@ class TUIChatSeparateViewModel extends ChangeNotifier { TIMUIKitChatConfig chatConfig = const TIMUIKitChatConfig(); ValueChanged? setInputField; String Function(V2TimMessage message)? abstractMessageBuilder; - Function(String userID)? onTapAvatar; + Function(String userID, TapDownDetails tapDetails)? onTapAvatar; V2TimGroupMemberFullInfo? _currentChatUserInfo; V2TimGroupInfo? _groupInfo; String groupMemberListSeq = "0"; List? groupMemberList = []; + double atPositionX = 0.0; + double atPositionY = 0.0; + int _activeAtIndex = -1; + List _showAtMemberList = []; + + int get activeAtIndex => _activeAtIndex; + + set activeAtIndex(int value) { + _activeAtIndex = value; + notifyListeners(); + } + + List get showAtMemberList => _showAtMemberList; + + set showAtMemberList(List value) { + _showAtMemberList = value; + notifyListeners(); + } V2TimGroupInfo? get groupInfo => _groupInfo; @@ -78,10 +97,10 @@ class TUIChatSeparateViewModel extends ChangeNotifier { notifyListeners(); } - String get currentSelectedMsgId => _currentSelectedMsgId; + String get currentPlayedMsgId => _currentPlayedMsgId; - set currentSelectedMsgId(String value) { - _currentSelectedMsgId = value; + set currentPlayedMsgId(String value) { + _currentPlayedMsgId = value; notifyListeners(); } @@ -167,6 +186,12 @@ class TUIChatSeparateViewModel extends ChangeNotifier { globalModel.refreshGroupApplicationList(); getGroupInfo(groupID ?? convID); loadGroupMemberList(groupID: groupID ?? convID); + } else { + _groupType = null; + isGroupExist = true; + _groupInfo = null; + groupMemberList?.clear(); + notifyListeners(); } if (conversationType == ConvType.c2c) { final List? friendRes = @@ -208,36 +233,29 @@ class TUIChatSeparateViewModel extends ChangeNotifier { List msgList = []; haveMoreData = false; - final previousResponse = await _messageService.getHistoryMessageListWithComplete( - count: 20, - getType: HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG, - userID: conversationType == ConvType.c2c ? conversationID : null, - groupID: conversationType == ConvType.group ? conversationID : null, - lastMsgSeq: max(seq, 0) - ); + final previousResponse = + await _messageService.getHistoryMessageListWithComplete( + count: 20, + getType: HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG, + userID: conversationType == ConvType.c2c ? conversationID : null, + groupID: conversationType == ConvType.group ? conversationID : null, + lastMsgSeq: max(seq, 0)); msgList = previousResponse?.messageList ?? []; haveMoreData = !(previousResponse?.isFinished ?? false); - - // final latestResponse = await _messageService.getHistoryMessageListWithComplete( - // count: 20, - // getType: HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_NEWER_MSG, - // userID: conversationType == ConvType.c2c ? conversationID : null, - // groupID: conversationType == ConvType.group ? conversationID : null, - // lastMsgSeq: max(seq - 1, 0) - // ); - // msgList = [...(latestResponse?.messageList.reversed ?? []), ...msgList]; haveMoreLatestData = true; - globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.notShowLatest); + globalModel.setMessageListPosition( + conversationID, HistoryMessagePosition.notShowLatest); msgList = await lifeCycle?.didGetHistoricalMessageList(msgList) ?? msgList; - msgList.insert(0, V2TimMessage( - userID: '', - isSelf: false, - elemType: 101, - msgID: msgList[0].msgID, - seq: msgList[0].seq, - timestamp: 9999 - )); + msgList.insert( + 0, + V2TimMessage( + userID: '', + isSelf: false, + elemType: 101, + msgID: msgList[0].msgID, + seq: msgList[0].seq, + timestamp: 9999)); globalModel.setMessageList(conversationID, msgList, needResetNewMessageCount: false); @@ -253,99 +271,141 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return haveMoreData; } - Future loadData({ - HistoryMsgGetTypeEnum? getType, - int lastMsgSeq = -1, - required int count, - String? lastMsgID, - LoadDirection direction = LoadDirection.previous, + // 加载聊天记录 + Future loadChatRecord({ + HistoryMsgGetTypeEnum? getType, // 获取聊天记录的方式 + int lastMsgSeq = -1, // 上一条消息的消息序号 + required int count, // 加载的消息数量 + String? lastMsgID, // 最后一条消息的ID + LoadDirection direction = + LoadDirection.previous, // 加载的方向,previous表示向上加载,latest表示向下加载 }) async { - // TODO: 这个函数写的也太复杂了,现在就先不动了,到时候2.0大版本得彻底改造下QAQ - if(direction == LoadDirection.latest){ - haveMoreLatestData = false; - }else{ - haveMoreData = false; - } - final currentHistoryMsgList = globalModel.messageListMap[conversationID]; - final response = await _messageService.getHistoryMessageListWithComplete( + try { + // 根据加载方向设置是否还能继续加载更多消息 + direction == LoadDirection.latest + ? haveMoreLatestData = false + : haveMoreData = false; + + // 获取当前聊天对话的历史消息列表 + final currentRecordList = globalModel.messageListMap[conversationID]; + + // 调用MessageService获取聊天记录 + final response = await _messageService.getHistoryMessageListWithComplete( count: count, - getType: getType ?? (direction == LoadDirection.previous - ? HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG - : HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_NEWER_MSG), + getType: getType ?? + (direction == LoadDirection.previous + ? HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG + : HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_NEWER_MSG), userID: conversationType == ConvType.c2c ? conversationID : null, groupID: conversationType == ConvType.group ? conversationID : null, lastMsgID: lastMsgID, - lastMsgSeq: lastMsgSeq); - if (response == null) { - return false; - } + lastMsgSeq: lastMsgSeq, + ); - if (lastMsgID != null && currentHistoryMsgList != null) { - List messageList = response.messageList; - List newList = []; - - if(direction == LoadDirection.latest){ - globalModel.receivedNewMessageCount = globalModel.receivedMessageListCount + messageList.length; - messageList = messageList.reversed.toList(); - newList = [...messageList, ...currentHistoryMsgList]; - }else{ - newList = [...currentHistoryMsgList, ...messageList]; + if (response == null) { + return false; } - final List msgList = - await lifeCycle?.didGetHistoricalMessageList(newList) ?? newList; - globalModel.setMessageList(conversationID, msgList, - needResetNewMessageCount: false); - } else { - List messageList = - await lifeCycle?.didGetHistoricalMessageList(response.messageList) ?? - response.messageList; - if (globalModel.loadingMessage[conversationID] != null) { - if (globalModel.loadingMessage[conversationID]!.isNotEmpty) { - if(direction == LoadDirection.previous){ - messageList = [ - ...?globalModel.loadingMessage[conversationID], - ...messageList - ]; - }else{ - messageList = messageList.reversed.toList(); - messageList = [ - ...messageList, - ...?globalModel.loadingMessage[conversationID], - ]; + // 根据加载方向更新是否还能继续加载更多消息 + if (direction == LoadDirection.latest) { + haveMoreLatestData = !response.isFinished; + } else { + haveMoreData = !response.isFinished; + } + notifyListeners(); + + if (response.messageList.isEmpty) { + return false; + } + + // 根据lastMsgID判断是否为分页加载 + if (lastMsgID != null && currentRecordList != null) { + List messageList = response.messageList; + List newList = []; + + // 根据加载方向拼接消息列表 + if (direction == LoadDirection.latest) { + globalModel.receivedNewMessageCount = + globalModel.receivedMessageListCount + messageList.length; + messageList = messageList.reversed.toList(); + newList = _combineMessageList(messageList, currentRecordList); + } else { + newList = _combineMessageList(currentRecordList, messageList); + } + + // 处理新获取的消息列表后回调 + final List msgList = + await lifeCycle?.didGetHistoricalMessageList(newList) ?? newList; + + // 更新聊天记录到全局model + globalModel.setMessageList( + conversationID, + msgList, + needResetNewMessageCount: false, + ); + } else { + // 处理新获取的消息列表后回调 + List receivedList = await lifeCycle + ?.didGetHistoricalMessageList(response.messageList) ?? + response.messageList; + + // 根据加载方向拼接消息列表 + if (globalModel.loadingMessage[conversationID]?.isNotEmpty ?? false) { + if (direction == LoadDirection.previous) { + receivedList = _combineMessageList( + globalModel.messageListMap[conversationID]!, receivedList); + } else { + receivedList = receivedList.reversed.toList(); + receivedList = _combineMessageList( + receivedList, globalModel.messageListMap[conversationID]!); } } else { globalModel.loadingMessage.remove(conversationID); } - } - globalModel.setMessageList(conversationID, messageList, - needResetNewMessageCount: false); - } - if (chatConfig.isShowGroupReadingStatus && - conversationType == ConvType.group && - response.messageList.isNotEmpty) { - _getMsgReadReceipt(response.messageList); - } - if (chatConfig.isReportGroupReadingStatus && - conversationType == ConvType.group && - response.messageList.isNotEmpty) { - _setMsgReadReceipt(response.messageList); - } - - if(direction == LoadDirection.latest){ - haveMoreLatestData = !response.isFinished; - if(!haveMoreLatestData){ - globalModel.setMessageListPosition(conversationID, HistoryMessagePosition.inTwoScreen); + // 更新聊天记录到全局model + globalModel.setMessageList( + conversationID, + receivedList, + needResetNewMessageCount: false, + ); } - }else{ - haveMoreData = !response.isFinished; + + // 获取已读未读状态 + if (chatConfig.isShowGroupReadingStatus && + conversationType == ConvType.group && + response.messageList.isNotEmpty) { + _getMsgReadReceipt(response.messageList); + } + if (chatConfig.isReportGroupReadingStatus && + conversationType == ConvType.group && + response.messageList.isNotEmpty) { + _setMsgReadReceipt(response.messageList); + } + + // 根据加载方向更新是否还能继续加载更多消息 + if (direction == LoadDirection.latest && !haveMoreLatestData) { + globalModel.setMessageListPosition( + conversationID, HistoryMessagePosition.inTwoScreen); + } + notifyListeners(); + + return haveMoreData; + } catch (e) { + // ignore: avoid_print + print('loadChatRecord error: $e'); + return false; } - return haveMoreData; + } + +// 拼接聊天记录 + List _combineMessageList( + List first, List second) { + return [...first, ...second]; } Future loadDataFromController({int? count}) { - return loadData( + return loadChatRecord( count: count ?? HistoryMessageDartConstant.getCount, //20 ); } @@ -357,7 +417,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier { _getMsgReadReceipt(List message) async { final msgID = message - .where((e) => (e.isSelf ?? false) && (e.needReadReceipt ?? false)) + .where((e) => (e.isSelf ?? true) && (e.needReadReceipt ?? false)) .map((e) => e.msgID ?? '') .toList(); if (msgID.isNotEmpty) { @@ -374,10 +434,26 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } + translateText(V2TimMessage message) async { + final String originText = message.textElem?.text ?? ""; + final String deviceLocale = TIM_getCurrentDeviceLocale(); + final String targetMessage = deviceLocale.split("-")[0]; + final translatedText = + await _messageService.translateText(originText, targetMessage); + + final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap( + json.decode(TencentUtils.checkString(message.localCustomData) ?? "{}")); + localCustomData.translatedText = translatedText; + message.localCustomData = json.encode(localCustomData.toMap()); + globalModel.onMessageModified(message); + TencentImSDKPlugin.v2TIMManager.v2TIMMessageManager.setLocalCustomData( + msgID: message.msgID!, localCustomData: message.localCustomData ?? ""); + } + _setMsgReadReceipt(List message) async { final msgIDList = List.empty(growable: true); for (var item in message) { - final isSelf = item.isSelf ?? false; + final isSelf = item.isSelf ?? true; final needReadReceipt = item.needReadReceipt ?? false; if (!isSelf && needReadReceipt && item.msgID != null) { msgIDList.add(item.msgID!); @@ -397,7 +473,6 @@ class TUIChatSeparateViewModel extends ChangeNotifier { markMessageAsRead() async { globalModel.unreadCountForConversation = 0; - // globalModel.receivedNewMessageCount = 0; if (conversationType == ConvType.c2c) { return _messageService.markC2CMessageAsRead(userID: conversationID); } @@ -472,15 +547,17 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - Future updateMessageFromController({required String msgID}) async { - V2TimMessage? newMessage = await tools.getExistingMessageByID( - msgID: msgID, - conversationType: conversationType ?? ConvType.c2c, - conversationID: conversationID); + Future updateMessageFromController( + {required String msgID, V2TimMessage? message}) async { + V2TimMessage? newMessage = message ?? + await tools.getExistingMessageByID( + msgID: msgID, + conversationType: conversationType ?? ConvType.c2c, + conversationID: conversationID); if (newMessage != null) { globalModel.onMessageModified(newMessage, conversationID); } else { - loadData( + loadChatRecord( count: HistoryMessageDartConstant.getCount, ); } @@ -531,7 +608,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier { }) : "", ); - if (isEditStatusMessage == false && globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + if (isEditStatusMessage == false && + globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { globalModel.updateMessage( sendMsgRes, convID, id, convType, groupType, setInputField); } @@ -570,7 +649,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList @@ -608,15 +688,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); } + return _sendMessage( convID: convID, id: textATMessageInfo.id as String, @@ -646,7 +727,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList @@ -654,6 +737,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier { globalModel.setMessageList(conversationID, currentHistoryMsgList); notifyListeners(); } + return _sendMessage( convID: convID, id: textMessageInfo.id as String, @@ -685,15 +769,17 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); } + return _sendMessage( convID: convID, id: soundMessageInfo.id as String, @@ -735,16 +821,22 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - Future?> sendReplyMessage( - {required String text, - required String convID, - required ConvType convType}) async { + Future?> sendReplyMessage({ + required String text, + required String convID, + required ConvType convType, + List? atUserIDList, + }) async { if (text.isEmpty) { return null; } if (_repliedMessage != null) { - final V2TimMsgCreateInfoResult? textMessageInfo = + V2TimMsgCreateInfoResult? textMessageInfo = await _messageService.createTextMessage(text: text); + if (atUserIDList != null && atUserIDList.isNotEmpty) { + textMessageInfo = await _messageService.createTextAtMessage( + text: text, atUserList: atUserIDList); + } final V2TimMessage? messageInfo = textMessageInfo!.messageInfo; final receiver = convType == ConvType.c2c ? convID : ''; final groupID = convType == ConvType.group ? convID : ''; @@ -753,7 +845,7 @@ class TUIChatSeparateViewModel extends ChangeNotifier { : null; if (messageInfo != null) { V2TimMessage messageInfoWithSender = - tools.setUserInfoForMessage(messageInfo, messageInfo.id!); + tools.setUserInfoForMessage(messageInfo, textMessageInfo.id!); final hasNickName = _repliedMessage?.nickName != null && _repliedMessage?.nickName != ""; final cloudCustomData = { @@ -843,10 +935,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { format: CompressFormat.jpeg, quality: 85); image = result?.path; } - } catch (e) { - // ignore: avoid_print - print(e); - } + // ignore: empty_catches + } catch (e) {} } final imageMessageInfo = await _messageService.createImageMessage( imagePath: image ?? imagePath, inputElement: inputElement); @@ -863,15 +953,17 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest){ - currentHistoryMsgList = [ - lifeCycleMsg ?? messageInfoWithSender, - ...currentHistoryMsgList - ]; - globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + lifeCycleMsg ?? messageInfoWithSender, + ...currentHistoryMsgList + ]; + globalModel.setMessageList(conversationID, currentHistoryMsgList); + notifyListeners(); } + return _sendMessage( convID: convID, messageInfo: lifeCycleMsg ?? messageInfoWithSender, @@ -894,7 +986,9 @@ class TUIChatSeparateViewModel extends ChangeNotifier { List currentHistoryMsgList = getOriginMessageList(); final videoMessageInfo = await _messageService.createVideoMessage( videoPath: videoPath, - type: 'mp4', + type: videoPath != null + ? videoPath.split(".")[videoPath.split(".").length - 1] + : 'mp4', duration: duration, inputElement: inputElement, snapshotPath: snapshotPath); @@ -909,15 +1003,17 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); } + return _sendMessage( convID: convID, messageInfo: lifeCycleMsg ?? messageInfoWithSender, @@ -954,15 +1050,17 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); } + return _sendMessage( convID: convID, messageInfo: lifeCycleMsg ?? messageInfoWithSender, @@ -995,13 +1093,14 @@ class TUIChatSeparateViewModel extends ChangeNotifier { return null; } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest) { + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList ]; globalModel.setMessageList(conversationID, currentHistoryMsgList); - notifyListeners(); } return _sendMessage( @@ -1126,10 +1225,12 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } // 注意重发消息需要先删除之前发送失败的图 - Future?> reSendFailMessage( - {required V2TimMessage message, - required String convID, - required ConvType convType}) async { + Future?> reSendFailMessage({ + required V2TimMessage message, + required String convID, + required ConvType convType, + List? atUserIDList, + }) async { await deleteMsg(message.msgID ?? "", id: message.id, webMessageInstance: message.messageFromWeb); int messageType = message.elemType; @@ -1138,7 +1239,11 @@ class TUIChatSeparateViewModel extends ChangeNotifier { String text = message.textElem!.text!; if (_repliedMessage != null) { res = await sendReplyMessage( - text: text, convID: convID, convType: convType); + text: text, + convID: convID, + convType: convType, + atUserIDList: atUserIDList, + ); } else { res = await sendTextMessage( text: text, convID: convID, convType: convType); @@ -1204,7 +1309,8 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - if(globalModel.getMessageListPosition(conversationID) != HistoryMessagePosition.notShowLatest){ + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { currentHistoryMsgList = [ lifeCycleMsg ?? messageInfoWithSender, ...currentHistoryMsgList @@ -1213,7 +1319,6 @@ class TUIChatSeparateViewModel extends ChangeNotifier { notifyListeners(); } - return _sendMessage( convID: convID, id: textMessageInfo.id as String, @@ -1235,8 +1340,16 @@ class TUIChatSeparateViewModel extends ChangeNotifier { final messageInfoWithSender = messageInfo.sender == null ? tools.setUserInfoForMessage(messageInfo, messageInfo.id!) : messageInfo; - currentHistoryMsgList = [messageInfoWithSender, ...currentHistoryMsgList]; - globalModel.setMessageList(conversationID, currentHistoryMsgList); + + if (globalModel.getMessageListPosition(conversationID) != + HistoryMessagePosition.notShowLatest) { + currentHistoryMsgList = [ + messageInfoWithSender, + ...currentHistoryMsgList + ]; + globalModel.setMessageList(conversationID, currentHistoryMsgList); + } + return _sendMessage( convID: conversationID, id: messageInfo.id as String, @@ -1316,26 +1429,6 @@ class TUIChatSeparateViewModel extends ChangeNotifier { } } - translateText(V2TimMessage message) async { - final String originText = message.textElem?.text ?? ""; - final String deviceLocale = - WidgetsBinding.instance?.window.locale.toLanguageTag() ?? "en"; - final String targetMessage = deviceLocale.split("-")[0]; - final translatedText = - await _messageService.translateText(originText, targetMessage); - - final LocalCustomDataModel localCustomData = LocalCustomDataModel.fromMap( - json.decode(TencentUtils.checkString(message.localCustomData) ?? "{}")); - localCustomData.translatedText = translatedText; - final result = await TencentImSDKPlugin.v2TIMManager.v2TIMMessageManager - .setLocalCustomData( - msgID: message.msgID!, - localCustomData: json.encode(localCustomData.toMap())); - if (result.code == 0 && TencentUtils.checkString(message.msgID) != null) { - updateMessageFromController(msgID: message.msgID!); - } - } - updateMultiSelectStatus(bool isSelect) { _isMultiSelect = isSelect; if (!isSelect) { diff --git a/lib/business_logic/separate_models/tui_group_profile_model.dart b/lib/business_logic/separate_models/tui_group_profile_model.dart index 47c11de..153ba22 100644 --- a/lib/business_logic/separate_models/tui_group_profile_model.dart +++ b/lib/business_logic/separate_models/tui_group_profile_model.dart @@ -26,7 +26,7 @@ class TUIGroupProfileModel extends ChangeNotifier { List? _groupMemberList; String _groupMemberListSeq = "0"; V2TimGroupInfo? _groupInfo; - Function(String userID)? onClickUser; + Function(String userID, TapDownDetails? tapDetails)? onClickUser; GroupProfileLifeCycle? get lifeCycle => _lifeCycle; @@ -180,7 +180,6 @@ class TUIGroupProfileModel extends ChangeNotifier { setGroupNotification(String notification) async { if (_groupInfo != null) { - _groupInfo?.notification = notification; final response = await _groupServices.setGroupInfo( info: V2TimGroupInfo.fromJson({ "groupID": _groupID, @@ -189,6 +188,7 @@ class TUIGroupProfileModel extends ChangeNotifier { })); if (response.code == 0) { notifyListeners(); + _groupInfo?.notification = notification; } } } @@ -327,7 +327,7 @@ class TUIGroupProfileModel extends ChangeNotifier { Future muteGroupMember( String userID, bool isMute, int? serverTime) async { - final muteTime = serverTime != null ? serverTime + 9999 : 51556926 * 10; + const muteTime = 315360000; final res = await _groupServices.muteGroupMember( groupID: _groupID, userID: userID, seconds: isMute ? muteTime : 0); if (res.code == 0) { @@ -335,7 +335,7 @@ class TUIGroupProfileModel extends ChangeNotifier { _groupMemberList!.indexWhere((e) => e!.userID == userID); if (targetIndex != -1) { final targetElem = _groupMemberList![targetIndex]; - targetElem?.muteUntil = isMute ? muteTime : 0; + targetElem?.muteUntil = isMute ? (serverTime ?? 0) + muteTime : 0; _groupMemberList![targetIndex] = targetElem; } notifyListeners(); diff --git a/lib/business_logic/separate_models/tui_profile_view_model.dart b/lib/business_logic/separate_models/tui_profile_view_model.dart index cdb5ee6..6e517e5 100644 --- a/lib/business_logic/separate_models/tui_profile_view_model.dart +++ b/lib/business_logic/separate_models/tui_profile_view_model.dart @@ -31,6 +31,11 @@ class TUIProfileViewModel extends ChangeNotifier { return _userProfile; } + set userProfile(UserProfile? value) { + _userProfile = value; + notifyListeners(); + } + bool? get isDisturb { return _isDisturb; } @@ -48,6 +53,9 @@ class TUIProfileViewModel extends ChangeNotifier { } loadData({required String userID, bool isNeedConversation = true}) async { + if(userID.isEmpty){ + return; + } V2TimFriendInfo? friendUserInfo; V2TimConversation? conversation; final userInfoList = @@ -159,8 +167,6 @@ class TUIProfileViewModel extends ChangeNotifier { if (res.code == 0) { _userProfile?.friendInfo!.userProfile!.allowType = allowType; notifyListeners(); - } else { - print("${res.code},${res.desc}"); } return res; } @@ -175,8 +181,6 @@ class TUIProfileViewModel extends ChangeNotifier { if (res.code == 0) { _userProfile?.friendInfo!.userProfile!.gender = gender; notifyListeners(); - } else { - print("${res.code},${res.desc}"); } return res; @@ -192,8 +196,6 @@ class TUIProfileViewModel extends ChangeNotifier { if (res.code == 0) { _userProfile?.friendInfo!.userProfile!.nickName = nickName; notifyListeners(); - } else { - print("${res.code},${res.desc}"); } return res; @@ -208,8 +210,6 @@ class TUIProfileViewModel extends ChangeNotifier { if (res.code == 0) { _userProfile?.friendInfo!.userProfile!.selfSignature = selfSignature; notifyListeners(); - } else { - print("${res.code},${res.desc}"); } return res; } @@ -297,8 +297,6 @@ class TUIProfileViewModel extends ChangeNotifier { }); notifyListeners(); - } else { - print("${res.code},${res.desc}"); } return res; } diff --git a/lib/business_logic/view_models/tui_chat_global_model.dart b/lib/business_logic/view_models/tui_chat_global_model.dart index fbbd5cf..d75acca 100644 --- a/lib/business_logic/view_models/tui_chat_global_model.dart +++ b/lib/business_logic/view_models/tui_chat_global_model.dart @@ -18,7 +18,12 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; enum ConvType { none, c2c, group } -enum HistoryMessagePosition { bottom, inTwoScreen, awayTwoScreen, notShowLatest } +enum HistoryMessagePosition { + bottom, + inTwoScreen, + awayTwoScreen, + notShowLatest +} class CurrentConversation { final String conversationID; @@ -37,6 +42,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { final Map _preloadImageMap = {}; final Map _historyMessagePositionMap = {}; final List _currentConversationList = []; + Map get preloadImageMap => _preloadImageMap; ChatLifeCycle? _lifeCycle; @@ -49,8 +55,9 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { late V2TimAdvancedMsgListener advancedMsgListener; int _unreadCountForConversation = 0; - // use for generate a new sliver list to show received message list - int _receivedNewMessageCount = 0; + + // use for generate a new sliver list to show recived messag list + int _recivedNewMessageCount = 0; TIMUIKitChatConfig chatConfig = const TIMUIKitChatConfig(); List? _groupApplicationList; String Function(V2TimMessage message)? _abstractMessageBuilder; @@ -58,7 +65,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { Map.from({}); // 0 normal 1 sending final Map _c2cMessageFromUserActiveMap = Map.from({}); final Map _c2cMessageActiveTimer = Map.from({}); - bool _showC2cMessageEditStatus = true; + bool _showC2cMessageEditStaus = true; final Map _c2cMessageStatusShowTimer = Map.from({}); Map loadingMessage = {}; @@ -73,8 +80,8 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { onRecvNewMessage: (V2TimMessage newMsg) { _onReceiveNewMsg(newMsg); }, - onSendMessageProgress: (V2TimMessage message, int progress) { - _onSendMessageProgress(message, progress); + onSendMessageProgress: (V2TimMessage messagae, int progress) { + _onSendMessageProgress(messagae, progress); }, onRecvMessageReadReceipts: (List receiptList) { _onReceiveMessageReadReceipts(receiptList); @@ -87,12 +94,14 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { onMessageDownloadProgressCallback(messageProgress); }, ); - // Future.delayed(const Duration(milliseconds: 200)).then((value) => initMessageMapFromLocal()); } bool get isDownloading => _isDownloading; + bool get hasWaiting => _waitingDownloadList.isNotEmpty; + Map get currentDownLoad => _waitingDownloadList.first; + void addWaitingList(String msgID) { print("add to waiting list success"); bool contains = false; @@ -114,43 +123,28 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { } downloadFile() async { - bool hasWait = _waitingDownloadList.isNotEmpty; - print(_waitingDownloadList); - print(_isDownloading); - print(!hasWaiting); - if (_isDownloading || !hasWait) { - print("no download return"); + if (_isDownloading || _waitingDownloadList.isEmpty) { return; } - Map nextDownLoad = _waitingDownloadList.first; - String downLoadMsgID = nextDownLoad["msgID"] ?? ""; - if (downLoadMsgID.isEmpty) { + final nextDownload = _waitingDownloadList.first; + final msgID = nextDownload["msgID"] ?? ""; + if (msgID.isEmpty || _messageListProgressMap[msgID] == 100) { return; } - if (_messageListProgressMap[downLoadMsgID] == 100) { - return; - } - // await Dio().download(downLoadMsgUrl, downLoadMsgSavePath, - // onReceiveProgress: (recv, total) { - // if (total != -1) { - // // print((received / total * 100).toStringAsFixed(0) + "%"); - // int progrss = (recv / total * 100).ceil(); - // if (progrss > 1) { - // setMessageProgress(downLoadMsgID, progrss); - // } - // //you can build progressbar feature too - // } - // }); - await _messageService.downloadMessage( - msgID: downLoadMsgID, messageType: 6, imageType: 0, isSnapshot: false); + _isDownloading = true; - // startDownloadProcess(context, theme, received); + await _messageService.downloadMessage( + msgID: msgID, + messageType: 6, + imageType: 0, + isSnapshot: false, + ); + print("start another download"); - // downloadFile(); } - int getReceived(msgID) { + int getRecevied(msgID) { return messageListProgressMap[msgID] ?? 0; } @@ -179,11 +173,11 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { } int get receivedMessageListCount { - return _receivedNewMessageCount; + return _recivedNewMessageCount; } set receivedNewMessageCount(int value) { - _receivedNewMessageCount = value; + _recivedNewMessageCount = value; } int get unreadCountForConversation => _unreadCountForConversation; @@ -222,7 +216,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { } setShowC2cEditStatus(bool show) { - _showC2cMessageEditStatus = show; + _showC2cMessageEditStaus = show; } /// set edit status from chats @@ -379,14 +373,14 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { _totalUnreadCount = 0; _groupApplicationList?.clear(); _totalUnreadCount = 0; - _receivedNewMessageCount = 0; + _recivedNewMessageCount = 0; _messageReadReceiptMap.clear(); _messageListProgressMap.clear(); notifyListeners(); } clearRecivedNewMessageCount() { - _receivedNewMessageCount = 0; + _recivedNewMessageCount = 0; } _preLoadImage(List msgList) { @@ -457,17 +451,18 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { _editStatusCheck(V2TimMessage msg) { bool isStatusMessage = false; - if (msg.customElem != null && msg.groupID == null) { + if (msg.customElem != null && + TencentUtils.checkString(msg.groupID) == null) { V2TimCustomElem customElem = msg.customElem!; String sender = msg.sender ?? ""; if (customElem.data!.isNotEmpty) { try { Map? data = json.decode(customElem.data ?? ""); if (data != null) { - String businessID = data["businessID"]; + var businessID = data["businessID"]; int? userAction = data["userAction"]; String? actionParam = data["actionParam"]; - if (businessID == "user_typing_status") { + if (businessID.toString() == "user_typing_status") { int? typingStatus = data["typingStatus"]; if (sender != "") { if (typingStatus != null) { @@ -501,7 +496,6 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { try { Map data = json.decode(msg.cloudCustomData ?? ""); Map? messageFeature = data["messageFeature"]; - print(data); if (messageFeature != null) { int needTyping = messageFeature["needTyping"]; if (needTyping == 1) { @@ -532,7 +526,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { } sendEditStatusMessage(bool isEditing, String toUser) async { - if (!_showC2cMessageEditStatus) { + if (!_showC2cMessageEditStaus) { return; } if (!(_c2cMessageFromUserActiveMap[toUser] ?? false)) { @@ -598,19 +592,27 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { } _checkFromUserisActive(msgComing); - final convID = newMsg.userID ?? newMsg.groupID; + final convID = TencentUtils.checkString(newMsg.userID) ?? newMsg.groupID; + final convType = TencentUtils.checkString(newMsg.groupID) != null + ? ConvType.group + : ConvType.c2c; if (convID != null && convID == currentSelectedConv) { final position = getMessageListPosition(convID); - if(position == HistoryMessagePosition.notShowLatest){ + if (position == HistoryMessagePosition.notShowLatest) { return; } if (position == HistoryMessagePosition.bottom && unreadCountForConversation == 0) { - markMessageAsRead( - convID: convID, - convType: currentSelectedConvType!, - ); - _receivedNewMessageCount = 0; + _unreadCountForConversation = 0; + if (chatConfig.isAutoReportRead) { + Future.delayed(const Duration(seconds: 1), () { + markMessageAsRead( + convID: convID, + convType: convType, + ); + }); + } + _recivedNewMessageCount = 0; final currentMsg = _messageListMap[convID] ?? []; _messageListMap[convID] = [newMsg, ...currentMsg]; notifyListeners(); @@ -619,14 +621,17 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { if (needReadReceipt && messageID != null && msgComing.groupID != null && - chatConfig.isReportGroupReadingStatus) { + chatConfig.isReportGroupReadingStatus && + chatConfig.isAutoReportRead) { // only group message send message read receipt - sendMessageReadReceipts([messageID]); + Future.delayed(const Duration(seconds: 1), () { + sendMessageReadReceipts([messageID]); + }); } } else { if (convID == currentSelectedConv) { unreadCountForConversation++; - _receivedNewMessageCount++; + _recivedNewMessageCount++; final currentMsg = _messageListMap[convID] ?? []; _messageListMap[convID] = [newMsg, ...currentMsg]; notifyListeners(); @@ -667,7 +672,9 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { onMessageModified(V2TimMessage modifiedMessage, [String? convID]) async { modifiedMessage.id = DateTime.now().millisecondsSinceEpoch.toString(); - final activeMessageList = _messageListMap[convID ?? currentSelectedConv]; + final String? exactId = TencentUtils.checkString(modifiedMessage.userID) ?? + TencentUtils.checkString(modifiedMessage.groupID); + final activeMessageList = _messageListMap[convID ?? exactId]; if (activeMessageList == null || activeMessageList.isEmpty) { return; } @@ -675,7 +682,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { await _lifeCycle?.modifiedMessageWillMount(modifiedMessage) ?? modifiedMessage; final msgID = newMsg.msgID; - _messageListMap[currentSelectedConv] = activeMessageList.map((item) { + _messageListMap[convID ?? exactId ?? ""] = activeMessageList.map((item) { if (item.msgID == msgID) { return newMsg; } @@ -690,7 +697,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { final isNotEmpty = _messageListMap[convID]?.isNotEmpty; if (isNotEmpty != null && isNotEmpty) { _messageListMap[convID] = _messageListMap[convID]!.map((element) { - final isSelf = element.isSelf ?? false; + final isSelf = element.isSelf ?? true; final isPeerRead = element.isPeerRead ?? false; if (isSelf && !isPeerRead) { element.isPeerRead = true; @@ -711,9 +718,8 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { } } notifyListeners(); - } catch (e) { - print(e); - } + // ignore: empty_catches + } catch (e) {} } _onSendMessageProgress(V2TimMessage messagae, int progress) { @@ -721,11 +727,23 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { } onMessageDownloadProgressCallback( - V2TimMessageDownloadProgress messageProgress) { + V2TimMessageDownloadProgress messageProgress) async { if (messageProgress.isFinish) { setMessageProgress(messageProgress.msgID, 100); setFileMessageLocation(messageProgress.msgID, messageProgress.path); downloadFile(); + if (messageProgress.type == 0) { + final messages = await _messageService + .findMessages(messageIDList: [messageProgress.msgID]); + final V2TimMessage? message = messages?.first; + if (message != null) { + updateAsyncMessage( + message, + TencentUtils.checkString(message.userID) ?? + TencentUtils.checkString(message.groupID) ?? + ""); + } + } return; } if (messageProgress.isError) { @@ -761,11 +779,9 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { required String convID, required ConvType convType, }) async { - _unreadCountForConversation = 0; if (convType == ConvType.c2c) { return _messageService.markC2CMessageAsRead(userID: convID); } - _messageService.markGroupMessageAsRead(groupID: convID); } @@ -888,7 +904,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { {bool needResetNewMessageCount = true}) { _messageListMap[conversationID] = messageList; if (needResetNewMessageCount) { - _receivedNewMessageCount = 0; + _recivedNewMessageCount = 0; } notifyListeners(); } @@ -926,6 +942,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { groupType != null ? GroupReceptAllowType.values[groupType.index] : null; if (chatConfig.isShowGroupReadingStatus && convType == ConvType.group && + sendMsgRes.data?.msgID != null && ((chatConfig.groupReadReceiptPermissionList != null && chatConfig.groupReadReceiptPermissionList! .contains(groupType)) || @@ -967,6 +984,7 @@ class TUIChatGlobalModel extends ChangeNotifier with TIMUIKitClass { if (listWithTimestamp.isEmpty || (listWithTimestamp[listWithTimestamp.length - 1].timestamp != null && + item.timestamp != null && (item.timestamp! - listWithTimestamp[listWithTimestamp.length - 1] .timestamp! > diff --git a/lib/business_logic/view_models/tui_conversation_view_model.dart b/lib/business_logic/view_models/tui_conversation_view_model.dart index 7a7ef52..6d8985f 100644 --- a/lib/business_logic/view_models/tui_conversation_view_model.dart +++ b/lib/business_logic/view_models/tui_conversation_view_model.dart @@ -1,6 +1,7 @@ // ignore_for_file: unnecessary_getters_setters import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; @@ -29,6 +30,8 @@ List removeDuplicates( } class TUIConversationViewModel extends ChangeNotifier { + final TUISelfInfoViewModel selfInfoViewModel = + serviceLocator(); final ConversationService _conversationService = serviceLocator(); final FriendshipServices _friendshipServices = @@ -39,23 +42,16 @@ class TUIConversationViewModel extends ChangeNotifier { late V2TimConversationListener _conversationListener; List _conversationList = []; static V2TimConversation? _selectedConversation; + bool _haveMoreData = true; int _totalUnReadCount = 0; String? _scrollToConversation; + final TUIChatGlobalModel globalChatModel = + serviceLocator(); + String _nextSeq = "0"; ConversationLifeCycle? _lifeCycle; - String? get scrollToConversation => _scrollToConversation; - - set scrollToConversation(String? value) { - _scrollToConversation = value; - notifyListeners(); - } - - void clearScrollToConversation(){ - _scrollToConversation = null; - } - List get conversationList { if (PlatformUtils().isWeb) { try { @@ -69,9 +65,8 @@ class TUIConversationViewModel extends ChangeNotifier { .toList(); _conversationList.removeWhere((element) => element?.isPinned == true); _conversationList = [...pinnedConversation, ..._conversationList]; + // ignore: empty_catches } catch (e) { - // ignore: avoid_print - print(e); } } else { _conversationList.sort((a, b) => b!.orderkey!.compareTo(a!.orderkey!)); @@ -79,6 +74,17 @@ class TUIConversationViewModel extends ChangeNotifier { return _conversationList; } + String? get scrollToConversation => _scrollToConversation; + + set scrollToConversation(String? value) { + _scrollToConversation = value; + notifyListeners(); + } + + void clearScrollToConversation() { + _scrollToConversation = null; + } + bool get haveMoreData { return _haveMoreData; } @@ -98,6 +104,11 @@ class TUIConversationViewModel extends ChangeNotifier { notifyListeners(); } + set selectedConversation(V2TimConversation? value) { + _selectedConversation = value; + notifyListeners(); + } + V2TimConversation? get selectedConversation { return _selectedConversation; } @@ -125,7 +136,9 @@ class TUIConversationViewModel extends ChangeNotifier { loadInitConversation() async { await loadData(count: 40); - _chatGlobalModel.initMessageMapFromLocalDatabase(_conversationList); + if (selfInfoViewModel.globalConfig?.isPreloadMessagesAfterInit ?? true) { + _chatGlobalModel.initMessageMapFromLocalDatabase(_conversationList); + } } initConversation() async { @@ -165,6 +178,7 @@ class TUIConversationViewModel extends ChangeNotifier { void setSelectedConversation(V2TimConversation conversation) { _selectedConversation = conversation; + notifyListeners(); } Future pinConversation({ @@ -182,6 +196,9 @@ class TUIConversationViewModel extends ChangeNotifier { false) { return null; } + + globalChatModel.setMessageList(convID, []); + if (convType == 1) { return _messageService.clearC2CHistoryMessage(userID: convID); } else { diff --git a/lib/business_logic/view_models/tui_search_view_model.dart b/lib/business_logic/view_models/tui_search_view_model.dart index 2d90d1a..2bc479d 100644 --- a/lib/business_logic/view_models/tui_search_view_model.dart +++ b/lib/business_logic/view_models/tui_search_view_model.dart @@ -1,5 +1,6 @@ // ignore_for_file: constant_identifier_names +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_services.dart'; @@ -91,10 +92,13 @@ class TUISearchViewModel extends ChangeNotifier { type: KeywordListMatchType.V2TIM_KEYWORD_LIST_MATCH_TYPE_OR.index, )); if (searchResult.code == 0 && searchResult.data != null) { - totalMsgInConversationCount = searchResult.data!.totalCount!; + final messageSearchResultItems = searchResult + .data!.messageSearchResultItems! + .firstWhereOrNull((element) => element.conversationID == conversationId); + totalMsgInConversationCount = messageSearchResultItems?.messageCount ?? 0; currentMsgListForConversation = [ ...currentMsgListForConversation, - ...(searchResult.data!.messageSearchResultItems?[0].messageList ?? []) + ...(messageSearchResultItems?.messageList ?? []) ]; } notifyListeners(); diff --git a/lib/data_services/core/core_services_implements.dart b/lib/data_services/core/core_services_implements.dart index e4f8504..14fd3af 100644 --- a/lib/data_services/core/core_services_implements.dart +++ b/lib/data_services/core/core_services_implements.dart @@ -1,7 +1,6 @@ // ignore_for_file: avoid_print import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart'; @@ -157,7 +156,7 @@ class CoreServicesImpl with CoreServices { onCallback = onTUIKitCallbackListener; } setGlobalConfig(config); - if (PlatformUtils().isIOS || PlatformUtils().isAndroid) { + if (!PlatformUtils().isWeb) { didLoginSuccess(); } } @@ -251,8 +250,8 @@ class CoreServicesImpl with CoreServices { } tuiFriendShipViewModel.userStatusList = currentUserStatusList; + // ignore: empty_catches } catch (e) { - print(e); } } @@ -265,7 +264,7 @@ class CoreServicesImpl with CoreServices { _userSig = userSig; V2TimCallback result = await TencentImSDKPlugin.v2TIMManager .login(userID: userID, userSig: userSig); - if (PlatformUtils().isIOS || PlatformUtils().isAndroid) { + if (!PlatformUtils().isWeb) { didLoginSuccess(); } if (result.code != 0) { @@ -294,7 +293,7 @@ class CoreServicesImpl with CoreServices { } }); - if (!kIsWeb && + if (PlatformUtils().isMobile && selfInfoViewModel.globalConfig?.isCheckDiskStorageSpace == true) { final diskSpace = await DiskSpace.getFreeDiskSpace; if (diskSpace != null && diskSpace < 1024) { diff --git a/lib/data_services/core/tim_uikit_config.dart b/lib/data_services/core/tim_uikit_config.dart index d347edf..cc8f38d 100644 --- a/lib/data_services/core/tim_uikit_config.dart +++ b/lib/data_services/core/tim_uikit_config.dart @@ -1,4 +1,6 @@ import 'package:flutter/cupertino.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_im_base/theme/tui_theme.dart'; class TIMUIKitConfig { /// Control if show online status of friends or contacts. @@ -18,8 +20,34 @@ class TIMUIKitConfig { /// The configuration of border radius for all the avatar shows in TUIKit. final BorderRadius? defaultAvatarBorderRadius; - const TIMUIKitConfig({ + /// You can use this function to customize the Modal that shows on desktop. + /// Do not specified or return `false` will use our default implementation. + final Future Function( + TUIKitWideModalOperationKey operationKey, + BuildContext context, + Widget Function(VoidCallback closeFunc) child, + TUITheme? theme, + double? width, + double? height, + Offset? offset, + String? initText, + BorderRadius? borderRadius, + bool? isDarkBackground, + String? title, + VoidCallback? onSubmit, + Widget? submitWidget, + VoidCallback? onConfirm, + VoidCallback? onCancel, + )? showDesktopModalFunc; + + /// Determines whether TUIKit should preload some messages after initialization for faster message display, + /// with a default value of `true`, and backward-compatibility. + final bool isPreloadMessagesAfterInit; + + const TIMUIKitConfig( { this.defaultAvatarAssetPath, + this.showDesktopModalFunc, + this.isPreloadMessagesAfterInit = true, this.defaultAvatarBorderRadius, this.isCheckDiskStorageSpace = true, this.isShowOnlineStatus = true, diff --git a/lib/data_services/core/tim_uikit_wide_modal_operation_key.dart b/lib/data_services/core/tim_uikit_wide_modal_operation_key.dart new file mode 100644 index 0000000..98627a4 --- /dev/null +++ b/lib/data_services/core/tim_uikit_wide_modal_operation_key.dart @@ -0,0 +1,43 @@ + +enum TUIKitWideModalOperationKey{ + + /// You could use this value for your own Modal usage. + custom, + + // The following values are used in TUIKit + + conversationSecondaryMenu, + chooseCountry, + beforeSendScreenShot, + showUserProfileFromChat, + addNewContact, + showBlockedUsers, + chooseContacts, + addFriend, + addGroup, + chooseGroupType, + settings, + contactUs, + aboutUs, + showConditionsAndTerms, + secondaryClickUserAvatar, + forward, + messageReadDetails, + mergerMessageList, + chooseMentionedMembers, + chatHistory, + groupAddOpt, + setMute, + setUnmute, + setAdmins, + deleteAdmin, + groupMembersList, + addGroupMembers, + kickOffGroupMembers, + confirmDeleteMessages, + confirmClearChatHistory, + confirmExitGroup, + confirmDisbandGroup, + confirmGeneral, + unableToSendDueToFolders +} \ No newline at end of file diff --git a/lib/data_services/group/group_services_implement.dart b/lib/data_services/group/group_services_implement.dart index 986d58e..89c3b2d 100644 --- a/lib/data_services/group/group_services_implement.dart +++ b/lib/data_services/group/group_services_implement.dart @@ -105,6 +105,7 @@ class GroupServicesImpl extends GroupServices { count: count, offset: offset); if (res.code != 0) { + _coreService.callOnCallback(TIMCallback( type: TIMCallbackType.API_ERROR, errorMsg: res.desc, diff --git a/lib/data_services/message/message_service_implement.dart b/lib/data_services/message/message_service_implement.dart index a1ae652..405567a 100644 --- a/lib/data_services/message/message_service_implement.dart +++ b/lib/data_services/message/message_service_implement.dart @@ -127,14 +127,14 @@ class MessageServiceImpl extends MessageService { lastMsgID: lastMsgID, lastMsgSeq: lastMsgSeq, messageTypeList: messageTypeList); - final reponseMessageList = res.data; + final responseMessageList = res.data; if (res.code != 0) { _coreService.callOnCallback(TIMCallback( type: TIMCallbackType.API_ERROR, errorMsg: res.desc, errorCode: res.code)); } - return reponseMessageList; + return responseMessageList; } @override @@ -812,4 +812,5 @@ class MessageServiceImpl extends MessageService { } return result.data?[text] ?? ""; } + } diff --git a/lib/i18n/strings.i18n.json b/lib/i18n/strings.i18n.json index 689dba7..b441b8d 100644 --- a/lib/i18n/strings.i18n.json +++ b/lib/i18n/strings.i18n.json @@ -1 +1 @@ -{"k_1fdhj9g":"This version does not support the message","k_06pujtm":"Accept all friend requests","k_0gyhkp5":"Require approval for friend requests","k_121ruco":"Reject all friend requests","k_05nspni":"Custom field","k_03fchyy":"Group profile photo","k_03i9mfe":"Group introduction","k_03agq58":"Group name","k_039xqny":"Group notification","k_003tr0a":"Group owner","k_002wddw":"Mute","k_0got6f7":"Unmute","k_1uaqed6":"[Custom]","k_0z2z7rx":"[Voice]","k_0y39ngu":"[Emoji]","k_0y1a2my":"[Image]","k_0z4fib8":"[Video]","k_0y24mcg":"[Location]","k_0pewpd1":"[Chat history]","k_13s8d9p":"Unknown message","k_003qkx2":"Calendar","k_003n2pz":"Camera","k_03idjo0":"Contact","k_003ltgm":"Location","k_02k3k86":"Mic","k_003pm7l":"Album","k_15ao57x":"Album write","k_164m3jd":"Local storage","k_03r6qyx":"We need your approval to get information.","k_02noktt":"Reject","k_00043x4":"Agree","k_003qzac":"Yesterday","k_003r39d":"2 days ago","k_03fqp9o":"Sun","k_03ibg5h":"Mon","k_03i7hu1":"Tue","k_03iaiks":"Wed","k_03el9pa":"Thu","k_03i7ok1":"Fri","k_03efxyg":"Sat","k_003q7ba":"Afternoon","k_003q7bb":"Morning","k_003pu3h":"Now","k_002rflt":"Delete","k_1don84v":"Failed to locate the original message","k_003q5fi":"Copy","k_003prq0":"Forward","k_002r1h2":"Multiple-choice","k_003j708":"Reference","k_003pqpr":"Recall","k_03ezhho":"Copied","k_11ctfsz":"Not implemented","k_1hbjg5g":"[Group system message]","k_03tvswb":"[Unknown message]","k_155cj23":"You've recalled a message.","k_0gapun3":"Edit it again","k_0003z7x":"You","k_002wfe4":"Read","k_002wjlg":"Unread","k_003nevv":"Cancel","k_001nmhu":"Open with another app","k_105682d":"Failed to load the image","k_0pytyeu":"Image saved successfully","k_0akceel":"Failed to save the image","k_003rk1s":"Save","k_04a0awq":"[Voice message]","k_105c3y3":"Failed to load the video","k_176rzr7":"Chat history","k_002r305":"Send","k_003n8b0":"Shoot","k_003tnp0":"File","k_0ylosxn":"Custom message","k_0jhdhtp":"Sending failed. The video cannot exceed 100 MB.","k_0am7r68":"Slide up to cancel","k_13dsw4l":"Release to cancel","k_15jl6qw":"Too short","k_0gx7vl6":"Press and hold to talk","k_15dlafd":"One-by-one forward","k_15dryxy":"Combine and forward","k_1eyhieh":"Are you sure you want to delete the selected message?","k_118prbn":"Search globally","k_003kv3v":"Search","k_17fmlyf":"Clear chat","k_0dhesoz":"Unpin from top","k_002sk7x":"Pin to top","k_003ll77":"Draft","k_003kfai":"Unknown","k_13dq4an":"Automatic approval","k_0l13cde":"Admin approval","k_11y8c6a":"Disallow group joining","k_1kvyskd":"Modification failed due to network disconnection","k_16payqf":"Group joining mode","k_0vzvn8r":"Modify group name","k_003rzap":"OK","k_038lh6u":"Group management","k_0k5wyiy":"Set admin","k_0goiuwk":"Mute all","k_1g889xx":"If you mute all, only the group owner and admin can speak.","k_0wlrefq":"Add group members to mute","k_0goox5g":"Mute","k_08daijh":"Admin role canceled successfully","k_0k5u935":"Add admin","k_003ngex":"Complete","k_03enyx5":"Group member","k_03erpei":"Admin","k_0qi9tno":"Group owner and admin","k_0uj7208":"Failed to view the group members due to network disconnection","k_0ef2a12":"Modify my nickname in group","k_1aajych":"2–20 characters, including digits, letters, and underscores","k_137pab5":"My nickname in group","k_0ivim6d":"No group notice","k_03eq6cn":"Group notice","k_002vxya":"Modify","k_03gu05e":"Chat room","k_03b4f3p":"Meeting group","k_03avj1p":"Public group","k_03asq2g":"Work group","k_03b3hbi":"Unknown group","k_03es1ox":"Group type","k_003mz1i":"Agree","k_003lpre":"Reject","k_003qk66":"Profile photo","k_003lhvk":"Nickname","k_003ps50":"Account","k_15lx52z":"Status","k_003qgkp":"Gender","k_003m6hr":"Date of birth","k_0003v6a":"Male","k_00043x2":"Female","k_03bcjkv":"Not set","k_11s0gdz":"Modify nickname","k_0p3j4sd":"Allows only letters, digits, and underscores","k_15lyvdt":"Modify status","k_0vylzjp":"None","k_1hs7ese":"Modify it later","k_03exjk7":"Remarks","k_0s3skfd":"Add to blocklist","k_17fpl3y":"Pin chat to top","k_0p3b31s":"Modify remarks","k_0003y9x":"None","k_11zgnfs":"Profile","k_1tez2xl":"No status","k_0vjj2kp":"Group chat history","k_003n2rp":"Select","k_1m9exwh":"Recent contacts","k_119nwqr":"The input cannot be empty","k_0pzwbmg":"Video saved successfully","k_0aktupv":"Failed to save the video","k_1yemzyd":"Received a message","k_13sajrj":"Emoji message","k_13sjeb7":"File message","k_0yd2ft8":"Group notification","k_13s7mxn":"Image message","k_13satlt":"Location message","k_00bbtsx":"Combined message","k_13sqwu4":"Voice message","k_13sqjjp":"Video message","k_03iqsh4":" $s to ","k_191t5n4":"$opUserNickName changed ","k_1pg6aoj":"$opUserNickName quit group chat","k_1f6zt3v":"Invite $invitedMemberString to the group","k_0y7zd07":"Remove $invitedMemberString from the group","k_1d5mshh":"User $joinedMemberString joined the group","k_0yenqf0":"$userName was","k_0spotql":"Set $adminMember as admin","k_0pg5zzj":"System message: $operationType","k_1c7z88n":"[File] $fileName","k_1c3us5n":"The current group does not support @all","k_11k579v":"Invalid statements detected","k_0qba4ns":" attempted to access your $yoursItem","k_0oozw9x":"$diffMinutes minutes ago","k_13hzn00":"$yesterday, yesterday","k_0n9pyxz":"The user does not exist","k_1bjwemh":"Search by user ID","k_02owlq8":"My user ID: $userID","k_1wu8h4x":"Me: $showName","k_16758qw":"Add friend","k_1shx4d9":"Status: $selfSignature","k_0i553x0":"Enter verification information","k_031ocwx":"Enter remarks and list","k_003ojje":"Remarks","k_003lsav":"List","k_167bdvq":"My friends","k_156b4ut":"Friend request sent","k_1loix7s":"Group type: $groupType","k_1lqbsib":"The group chat does not exist","k_03h153m":"Search by group ID","k_0oxak3r":"Group request sent","k_1uh417q":"$displayName recalled a message","k_1aszp2k":"Are you sure you want to send the message again?","k_0h1ygf8":"Call initiated","k_0h169j0":"Call canceled","k_0h13jjk":"Call accepted","k_0h19hfx":"Call rejected","k_0obi9lh":"No answer","k_0ohzb9l":"Call duration: $callTime","k_0y9u662":"$appName currently does not support this file type. You can use another app to open and preview the file.","k_1ht1b80":"Receiving","k_0d5z4m5":"Select reminder receiver","k_1665ltg":"Initiate call","k_003kthh":"Photo","k_119ucng":"The image cannot be empty","k_0w9x8gw":"Selected successfully: $successPath","k_1np495n":"$messageString[Someone@me]","k_1m797yi":"$messageString[@all]","k_1uaov41":"Search for chat content","k_0bxm97s":"Admin ($adminNum/10)","k_0jayw3z":"Group members ($groupMemberNum members)","k_0h1svv1":"Delete group member","k_0h1g636":"Add group member","k_01yfa4o":"$memberCount members","k_0hpukyx":"View more group members","k_0qtsar0":"Mute notifications","k_03xd79d":"Status: $signature","k_1m9dftc":"All contacts","k_0em4gyz":"All group chats","k_002twmj":"Group chat","k_09kga0d":"More chat history","k_1ui5lzi":"$count messages are found","k_09khmso":"Related chat records","k_1kevf4k":"Chat history with $receiver","k_03ignw6":"All","k_03icaxo":"Custom","k_1969986":"[Voice Call]:$callingLastMsgShow","k_1960dlr":"[Video Call]:$callingLastMsgShow","k_1qbg9xc":"$option8 to ","k_1wq5ubm":"$option7 changed ","k_0y5pu80":"$option6 quit group chat","k_0nl7cmd":"Invite $option5 to the group","k_1ju5iqw":"Remove $option4 from the group","k_1ovt677":"User $option3 joined the group","k_0k05b8b":"$option2 was ","k_0wm4xeb":"System message: $option2","k_0nbq9v3":"Call duration: $option2","k_0i1kf53":"[File] $option2","k_1gnnby6":" attempted to access your $option2","k_1wh4atg":"$option2 minutes ago","k_07sh7g1":"$option2, yesterday","k_1pj8xzh":"My user ID: $option2","k_0py1evo":"Status: $option2","k_1kvj4i2":"$option2 recalled a message","k_1v0lbpp":"$option2 currently does not support this file type. You can use another app to open and preview the file.","k_0torwfz":"Selected successfully: $option2","k_0i1bjah":"$option1 recalled a message","k_1qzxh9q":"Call duration: $option3","k_0wrgmom":"[Voice Call]:$option1","k_06ix2f0":"[Video Call]:$option2","k_08o3z5w":"[File] $option1","k_0ezbepg":"$option2[Someone@me]","k_1ccnht1":"$option2[@all]","k_1k3arsw":"Admin ($option2/10)","k_1d4golg":"Group members ($option1 members)","k_1bg69nt":"$option1 members","k_00gjqxj":"Status: $option1","k_0c29cxr":"$option1 messages are found","k_1twk5rz":"Chat history with $option1","k_18o68ro":"Allow ","k_1onpf8u":" to access your camera to take photos, record videos, and make video calls.","k_17irga5":" to access your microphone to send voice messages, record videos, and make voice/video calls.","k_0572kc4":" to access your photos to send images and videos.","k_0slykws":" to access your album to save images and videos.","k_119pkcd":" to access your files to view, select and send files in a chat.","k_03c49qt":"Authorize now","k_0nt2uyg":"Back to the bottom","k_04l16at":"$option1 new messages","k_13p3w93":"Someone @ me","k_18w5uk6":"@ all","k_0jmujgh":"You are receiving other files","k_12s5ept":"Message details","k_0mxa4f4":"$option1 read","k_061tue3":"$option2 unread","k_1vn4xq1":"remove $adminMember from admin","k_0e35hsw":"Please allow us to use your camera to capture photos and videos sending to your friends and make video calls.","k_0dj6yr7":"Please allow us to use your microphone for sending voice message, make video/audio calls.","k_003qnsl":"Save","k_0s3rtpw":"Please allow us to access the media and files on your devices, in order to select and send to your friend, or save from them.","k_0tezv85":" Would like to access $option2","k_002rety":" permission. ","k_0gqewd3":"Later","k_03eq4s1":"Authorize Now","k_18qjstb":"Transfer Group","k_0on1aj2":"$option2 messages @ me","k_09j4izl":"[Someone @ me] ","k_1oqtjw0":"[@ all] ","k_1x5a9vb":"This is: $option1","k_14n31e7":"Add Group","k_08nc5j1":"Group type: $option1","k_1josu12":"$option1 group joining request(s)","k_0n2x5s0":"Verification message: $option2","k_03c1nx0":"Agreed","k_03aw9w8":"Rejected","k_038ryos":"Handle now","k_0gw8pum":"Add Group","k_1gcvfrj":"Please fill in the remarks","k_002v9zj":"确认","k_10oqrki":"轻触拍照","k_0f8b3ws":"加载失败","k_11cm5lm":"手动聚焦","k_002uzrd":"预览","k_003qkn3":"录像","k_003k6a7":"拍照","k_0bqpqco":"拍照按钮","k_1626ozl":"停止录像","k_003lvmu":"前置","k_003lued":"后置","k_003lwzh":"外置","k_002qzi3":"关闭","k_003pufb":"自动","k_0apm0ze":"拍照时闪光","k_157zog5":"始终闪光","k_0cfyqhy":"$option1 画面预览","k_0phctlz":"闪光模式: $option2","k_02vfqe0":"切换至 $option3 摄像头","k_0f0y9ex":"说话时间太短","k_0ln70tk":"无法打开URL","k_11a3jdv":"轻触拍照,长按摄像","k_1k18miv":"请传入离开群组生命周期函数,提供返回首页或其他页面的导航方法。","k_1fu9ahv":"全员禁言状态","k_0gmwbnd":"全员禁言中","k_0got2zr":"您被禁言","k_0y9jck8":"你必须自定义search bar,并处理点击跳转","k_0yum3tv":"如使用自定义区域,请在profileWidgetBuilder传入对应组件","k_09kalj0":"清空聊天记录","k_14j5iul":"删除并退出","k_125ru1w":"解散该群","k_0jtutmw":"退出后不会接收到此群聊消息","k_0jtzmqa":"解散后不会接收到此群聊消息","k_0r8fi93":"好友添加成功","k_02qw14e":"好友申请已发出","k_0n3md5x":"当前用户在黑名单","k_094phq4":"好友添加失败","k_129scag":"好友删除成功","k_129uzfn":"好友删除失败","k_1666isy":"清除好友","k_1679vrd":"加为好友","k_1ualc52":"看看对方带来的数据是啥","k_0szluvp":"设置对方在线状态","k_0f4rnf8":"该用户已是好友","k_1tdkom4":"您已是群成员","k_1p2lyuz":"对方正在输入中...","k_1g8wfpy":"...共$option1人","k_12rv9vw":"回应详情","k_0havgi0":"[查看详情 >>](${linkMessage.link})","k_0n9p7g8":"群组不存在","k_1tdh5vn":"您不是群成员","k_0h1q57v":"暂无群成员","k_0y5drq1":"[查看详情 >>]($option1)","k_03pjp61":"[表情消息]","k_1jpvzul":"[自定义消息]","k_03u3bh1":"[文件消息]","k_1odsnsw":"[群消息]","k_03sel4t":"[图片消息]","k_03sfw3r":"[位置消息]","k_03xpuwq":"[合并消息]","k_07ycxwo":"[没有元素]","k_03rc9vz":"[文本消息]","k_046uopf":"[视频消息]","k_0ehmsun":"设备存储空间不足,建议清理,以获得更好使用体验","k_003kmos":"图片","k_002s86q":"视频","k_06bk5ei":"视频消息仅限 mp4 格式","k_13opfxf":"Web网页端不支持搜索","k_1i0o0y2":"暂时仅限 Android/iOS 端","k_045dtzl":"$option1的聊天记录","k_0t0131u":"群资料信息","k_18ok8xz":"消息接收方式","k_03ax3ks":"群资料","k_0sqvoqo":"将 $option1 设置为管理员","k_1gbg1v8":"将 $option1 取消管理员","k_17k64g4":"群聊创建成功!","k_05mn217":"暂未安装表情包插件,如需使用表情相关功能,请根据本文档安装:https://cloud.tencent.com/document/product/269/70746","k_14j17nz":"暂无表情包","k_0fvjexh":"正在下载中","k_1cdagzz":"已加入待下载队列,其他文件下载中","k_0g4vojc":"开始下载","k_1g32es3":"[调皮]@2x.png","k_1g8qorz":"[爱你]@2x.png","k_1g4hmx6":"[爱情]@2x.png","k_1g6b558":"[爱心]@2x.png","k_1g3m4su":"[傲慢]@2x.png","k_1g2jym7":"[白眼]@2x.png","k_0cgkxuw":"[棒棒糖]@2x.png","k_1g48br2":"[抱抱]@2x.png","k_1g49ol8":"[抱拳]@2x.png","k_1g0ras3":"[爆筋]@2x.png","k_1ghy881":"[鄙视]@2x.png","k_1g86bmv":"[闭嘴]@2x.png","k_1g1xs1p":"[鞭炮]@2x.png","k_1g8i6ri":"[便便]@2x.png","k_1g2u5kf":"[擦汗]@2x.png","k_1g60uwh":"[彩带]@2x.png","k_1g1o0d0":"[彩球]@2x.png","k_1g6a6yq":"[菜刀]@2x.png","k_1g6vqo2":"[差劲]@2x.png","k_1g0kvjc":"[钞票]@2x.png","k_1g65x7e":"[车厢]@2x.png","k_0e1tjol":"[打哈欠]@2x.png","k_1g65n58":"[大兵]@2x.png","k_1g7se7o":"[大哭]@2x.png","k_1g03868":"[蛋糕]@2x.png","k_1h8nm66":"[刀]@2x.png","k_1g3dlpi":"[得意]@2x.png","k_1g3u434":"[灯泡]@2x.png","k_1giuqs7":"[凋谢]@2x.png","k_1g8r0r9":"[多云]@2x.png","k_1g7k6i1":"[发呆]@2x.png","k_1g44zsp":"[发抖]@2x.png","k_1g5l96i":"[飞机]@2x.png","k_1g7wsqj":"[飞吻]@2x.png","k_1g49luq":"[奋斗]@2x.png","k_1gixbsm":"[风车]@2x.png","k_1g6cqbq":"[尴尬]@2x.png","k_1g6jbw5":"[勾引]@2x.png","k_1g3lwo1":"[鼓掌]@2x.png","k_1g13nkj":"[害羞]@2x.png","k_1g0mt47":"[憨笑]@2x.png","k_0bxujkf":"[红灯笼]@2x.png","k_0hhaeh8":"[红双喜]@2x.png","k_1g0jnts":"[坏笑]@2x.png","k_1g46g9c":"[挥手]@2x.png","k_1g4vi9g":"[回头]@2x.png","k_1gf7hes":"[饥饿]@2x.png","k_1g6mvsm":"[激动]@2x.png","k_1gku5mf":"[街舞]@2x.png","k_1g4hidg":"[惊恐]@2x.png","k_1gjbrtu":"[惊讶]@2x.png","k_1g6sand":"[咖啡]@2x.png","k_1g4s8rj":"[磕头]@2x.png","k_1g1wn34":"[可爱]@2x.png","k_1g3l0wd":"[可怜]@2x.png","k_1ggaon9":"[抠鼻]@2x.png","k_1ggvcb0":"[骷髅]@2x.png","k_1h8yqjt":"[酷]@2x.png","k_0jac97i":"[快哭了]@2x.png","k_1h8oiby":"[困]@2x.png","k_1g0s5hg":"[蜡烛]@2x.png","k_1g1iuer":"[篮球]@2x.png","k_1g2xjfi":"[冷汗]@2x.png","k_0s5oyqw":"[礼品袋]@2x.png","k_1g1qqvf":"[礼物]@2x.png","k_1g2slew":"[流汗]@2x.png","k_1g3z9xx":"[流泪]@2x.png","k_1g6pabn":"[麻将]@2x.png","k_0pkaxul":"[麦克风]@2x.png","k_1g7m0zj":"[猫咪]@2x.png","k_0ibvtpo":"[么么哒]@2x.png","k_1g1hoh1":"[玫瑰]@2x.png","k_1gfzeow":"[米饭]@2x.png","k_1g5l15p":"[面条]@2x.png","k_1g2hfa6":"[奶瓶]@2x.png","k_1gix9pj":"[难过]@2x.png","k_1giqn6g":"[闹钟]@2x.png","k_1h8kd64":"[怒]@2x.png","k_1g0vui9":"[怄火]@2x.png","k_1g1jsj7":"[皮球]@2x.png","k_1ghdluw":"[啤酒]@2x.png","k_1gl6ec7":"[瓢虫]@2x.png","k_1g7gg5p":"[撇嘴]@2x.png","k_1g8psin":"[乒乓]@2x.png","k_1gjzu3p":"[汽车]@2x.png","k_1h8mr0k":"[强]@2x.png","k_1g45y2n":"[敲打]@2x.png","k_1gkaxsl":"[青蛙]@2x.png","k_0jcfnoo":"[糗大了]@2x.png","k_1g4njy1":"[拳头]@2x.png","k_1h8mqr3":"[弱]@2x.png","k_1h926fg":"[色]@2x.png","k_1g6rtbq":"[沙发]@2x.png","k_1giirh6":"[删除]@2x.png","k_1g14ny9":"[闪电]@2x.png","k_1g6bmsr":"[胜利]@2x.png","k_1g1rytx":"[示爱]@2x.png","k_1g52fbz":"[手枪]@2x.png","k_1h90dam":"[衰]@2x.png","k_1gigiae":"[睡觉]@2x.png","k_1gijchz":"[太阳]@2x.png","k_1g1sgji":"[跳绳]@2x.png","k_1gjwuri":"[跳跳]@2x.png","k_1g0juhk":"[偷笑]@2x.png","k_1h8nzla":"[吐]@2x.png","k_1g6cv0i":"[委屈]@2x.png","k_1g46l5g":"[握手]@2x.png","k_1g2pgkd":"[西瓜]@2x.png","k_1ging9p":"[下雨]@2x.png","k_1h8nzil":"[吓]@2x.png","k_1g7q7wr":"[献吻]@2x.png","k_1gl6uum":"[香蕉]@2x.png","k_1g23fys":"[象棋]@2x.png","k_0j75rdh":"[心碎了]@2x.png","k_1g6ajj2":"[信封]@2x.png","k_1g21prz":"[熊猫]@2x.png","k_1h8octi":"[嘘]@2x.png","k_1h91zox":"[药]@2x.png","k_1ghttfl":"[疑问]@2x.png","k_1ghk7sz":"[阴险]@2x.png","k_0gl37zz":"[右车头]@2x.png","k_0ifkj1p":"[右哼哼]@2x.png","k_0g1yh2e":"[右太极]@2x.png","k_1g9dkfc":"[雨伞]@2x.png","k_1g8jl88":"[月亮]@2x.png","k_1h8lhqj":"[晕]@2x.png","k_1gi9x2q":"[再见]@2x.png","k_1g6dwwv":"[炸弹]@2x.png","k_1fzmkfi":"[折磨]@2x.png","k_1g6jbiw":"[纸巾]@2x.png","k_1ggjnwu":"[咒骂]@2x.png","k_1g4qlq8":"[猪头]@2x.png","k_1g1lqzz":"[抓狂]@2x.png","k_1g80j3u":"[转圈]@2x.png","k_1g0z55s":"[龇牙]@2x.png","k_1g3ju6v":"[钻戒]@2x.png","k_0gl51l6":"[左车头]@2x.png","k_0iflllk":"[左哼哼]@2x.png","k_0g1y3ir":"[左太极]@2x.png","k_026hiq5":"消息列表加载中","k_003tu8k":"爱你","k_003myvp":"傲慢","k_003kddw":"白眼","k_039yfhv":"棒棒糖","k_003nu3p":"抱抱","k_003nijr":"抱拳","k_003mg88":"爆筋","k_002v17e":"鄙视","k_003qhy4":"闭嘴","k_003l5fq":"鞭炮","k_003uacl":"便便","k_003oq1g":"擦汗","k_003qvey":"彩带","k_003jci7":"彩球","k_003pyu1":"菜刀","k_003q97d":"差劲","k_003po5d":"车厢","k_03eadb2":"打哈欠","k_003pnuf":"大兵","k_003kg57":"蛋糕","k_003mxkt":"得意","k_003onu3":"灯泡","k_002uv8s":"凋谢","k_003kqy0":"调皮","k_003tyum":"多云","k_003pv9u":"发呆","k_036o6mu":"发抖t","k_003nogx":"飞机","k_003q7wg":"飞吻","k_003m0jd":"奋斗","k_002ult9":"风车","k_003r8gt":"尴尬","k_003qy4u":"勾引","k_003mnoa":"鼓掌","k_003lmw8":"害羞","k_003mb30":"憨笑","k_03bj41g":"红灯笼","k_03dxw2f":"红双喜","k_003mk57":"坏笑","k_003nmvf":"挥手","k_003r2i7":"回头","k_002s6f3":"饥饿","k_003qd0t":"激动","k_002vgi4":"街舞","k_003nz33":"惊恐","k_002wh4p":"惊讶","k_003ozpu":"咖啡","k_003qvs4":"磕头","k_003l3wb":"可爱","k_003nuwm":"可怜","k_002rw1q":"抠鼻","k_002tujb":"骷髅","k_00030eq":"酷","k_03i8ath":"快哭了","k_000421h":"困","k_003l5i7":"蜡烛","k_003j72g":"篮球","k_003ofwl":"冷汗","k_02mw65v":"礼品袋","k_003ku40":"礼物","k_003ookz":"流汗","k_003on72":"流泪","k_003rjy0":"麻将","k_003q2f8":"猫咪","k_03et393":"么么哒","k_003j7j2":"玫瑰","k_002sr0b":"米饭","k_003nnza":"面条","k_003jef9":"奶瓶","k_002umn0":"难过","k_002rjib":"闹钟","k_0003zcn":"怒","k_003jzwq":"怄火","k_003j4js":"皮球","k_002r5ir":"啤酒","k_002ubu4":"瓢虫","k_003ppo6":"撇嘴","k_003ty3o":"乒乓","k_002vxwe":"汽车","k_00043hb":"强","k_003nmbo":"敲打","k_002tfhq":"青蛙","k_03i7lrn":"糗大了","k_003r03m":"拳头","k_00043h0":"弱","k_000345z":"色","k_003qmp9":"沙发","k_003it8a":"闪电","k_003pxow":"胜利","k_003kw8e":"示爱","k_003n99g":"手枪","k_00035cl":"衰","k_002vl3h":"睡觉","k_002rgqk":"太阳","k_003m9d1":"跳绳","k_002vobp":"跳跳","k_003mkoz":"偷笑","k_00041px":"吐","k_003rjh5":"委屈","k_003j36u":"西瓜","k_002re92":"下雨","k_00041py":"吓","k_003q06o":"献吻","k_002ubjp":"香蕉","k_003o2tr":"象棋","k_03ie6pa":"心碎了","k_003rao5":"信封","k_003l3us":"熊猫","k_000424d":"嘘","k_00033yi":"药","k_002qtyy":"疑问","k_002qe0o":"阴险","k_03gu7us":"右车头","k_03ere8m":"右哼哼","k_003uqk3":"雨伞","k_003tzdv":"月亮","k_0003z00":"晕","k_002vdrd":"再见","k_003ra1w":"炸弹","k_003lcad":"折磨","k_003q7sz":"纸巾","k_002thn9":"咒骂","k_003qx7f":"猪头","k_003l044":"抓狂","k_003qg4h":"转圈","k_003kb97":"龇牙","k_03gu53l":"左车头","k_03erd1f":"左哼哼","k_003nyvl":"爱情","k_003r85z":"爱心","k_003mk8j":"钞票","k_003pwfj":"大哭","k_00042w5":"刀","k_003nmtr":"握手","k_03c529p":"右太极","k_003n4mk":"钻戒","k_03c5488":"左太极","k_1llp7tu":"该用户不存在","k_0tbyqyb":"加载中…","k_0td1p3f":"保存中…","k_1klqdh1":"仅限汉字、英文、数字和下划线","k_03el5lp":"未填写","k_1ui0gai":"搜索指定内容","k_003nvk2":"消息","k_03agld7":"群提示","k_002wkr3":"翻译","k_13g4hxv":"翻译完成","k_1qqgjra":"$option3条未读消息","k_0uubyjr":"以下为未读消息"} \ No newline at end of file +{"k_1fdhj9g":"This version does not support the message","k_06pujtm":"Accept all friend requests","k_0gyhkp5":"Require approval for friend requests","k_121ruco":"Reject all friend requests","k_05nspni":"Custom field","k_03fchyy":"Group profile photo","k_03i9mfe":"Group introduction","k_03agq58":"Group name","k_039xqny":"Group notification","k_003tr0a":"Group owner","k_002wddw":"Mute","k_0got6f7":"Unmute","k_1uaqed6":"[Custom]","k_0z2z7rx":"[Voice]","k_0y39ngu":"[Emoji]","k_0y1a2my":"[Image]","k_0z4fib8":"[Video]","k_0y24mcg":"[Location]","k_0pewpd1":"[Chat history]","k_13s8d9p":"Unknown message","k_003qkx2":"Calendar","k_003n2pz":"Camera","k_03idjo0":"Contact","k_003ltgm":"Location","k_02k3k86":"Mic","k_003pm7l":"Album","k_15ao57x":"Album write","k_164m3jd":"Local storage","k_03r6qyx":"We need your approval to get information.","k_02noktt":"Reject","k_00043x4":"Agree","k_003qzac":"Yesterday","k_003r39d":"2 days ago","k_03fqp9o":"Sun","k_03ibg5h":"Mon","k_03i7hu1":"Tue","k_03iaiks":"Wed","k_03el9pa":"Thu","k_03i7ok1":"Fri","k_03efxyg":"Sat","k_003q7ba":"Afternoon","k_003q7bb":"Morning","k_003pu3h":"Now","k_002rflt":"Delete","k_1don84v":"Failed to locate the original message","k_003q5fi":"Copy","k_003prq0":"Forward","k_002r1h2":"Multiple-choice","k_003j708":"Reference","k_003pqpr":"Recall","k_03ezhho":"Copied","k_11ctfsz":"Not implemented","k_1hbjg5g":"[Group system message]","k_03tvswb":"[Unknown message]","k_155cj23":"You've recalled a message.","k_0gapun3":"Edit it again","k_0003z7x":"You","k_002wfe4":"Read","k_002wjlg":"Unread","k_003nevv":"Cancel","k_001nmhu":"Open with another app","k_105682d":"Failed to load the image","k_0pytyeu":"Image saved successfully","k_0akceel":"Failed to save the image","k_003rk1s":"Save","k_04a0awq":"[Voice message]","k_105c3y3":"Failed to load the video","k_176rzr7":"Chat history","k_002r305":"Send","k_003n8b0":"Shoot","k_003tnp0":"File","k_0ylosxn":"Custom message","k_0jhdhtp":"Sending failed. The video cannot exceed 100 MB.","k_0am7r68":"Slide up to cancel","k_13dsw4l":"Release to cancel","k_15jl6qw":"Too short","k_0gx7vl6":"Press and hold to talk","k_15dlafd":"One-by-one forward","k_15dryxy":"Combine and forward","k_1eyhieh":"Are you sure you want to delete the selected message?","k_118prbn":"Search globally","k_003kv3v":"Search","k_17fmlyf":"Clear chat","k_0dhesoz":"Unpin from top","k_002sk7x":"Pin to top","k_003ll77":"Draft","k_003kfai":"Unknown","k_13dq4an":"Automatic approval","k_0l13cde":"Admin approval","k_11y8c6a":"Disallow group joining","k_1kvyskd":"Modification failed due to network disconnection","k_16payqf":"Group joining mode","k_0vzvn8r":"Modify group name","k_003rzap":"OK","k_038lh6u":"Group management","k_0k5wyiy":"Set admin","k_0goiuwk":"Mute all","k_1g889xx":"If you mute all, only the group owner and admin can speak.","k_0wlrefq":"Add group members to mute","k_0goox5g":"Mute","k_08daijh":"Admin role canceled successfully","k_0k5u935":"Add admin","k_003ngex":"Complete","k_03enyx5":"Group member","k_03erpei":"Admin","k_0qi9tno":"Group owner and admin","k_0uj7208":"Failed to view the group members due to network disconnection","k_0ef2a12":"Modify my nickname in group","k_1aajych":"2–20 characters, including digits, letters, and underscores","k_137pab5":"My nickname in group","k_0ivim6d":"No group notice","k_03eq6cn":"Group notice","k_002vxya":"Modify","k_03gu05e":"Chat room","k_03b4f3p":"Meeting group","k_03avj1p":"Public group","k_03asq2g":"Work group","k_03b3hbi":"Unknown group","k_03es1ox":"Group type","k_003mz1i":"Agree","k_003lpre":"Reject","k_003qk66":"Profile photo","k_003lhvk":"Nickname","k_003ps50":"Account","k_15lx52z":"Status","k_003qgkp":"Gender","k_003m6hr":"Date of birth","k_0003v6a":"Male","k_00043x2":"Female","k_03bcjkv":"Not set","k_11s0gdz":"Modify nickname","k_0p3j4sd":"Allows only letters, digits, and underscores","k_15lyvdt":"Modify status","k_0vylzjp":"None","k_1hs7ese":"Modify it later","k_03exjk7":"Remarks","k_0s3skfd":"Add to blocklist","k_17fpl3y":"Pin chat to top","k_0p3b31s":"Modify remarks","k_0003y9x":"None","k_11zgnfs":"Profile","k_1tez2xl":"No status","k_0vjj2kp":"Group chat history","k_003n2rp":"Select","k_1m9exwh":"Recent contacts","k_119nwqr":"The input cannot be empty","k_0pzwbmg":"Video saved successfully","k_0aktupv":"Failed to save the video","k_1yemzyd":"Received a message","k_13sajrj":"Emoji message","k_13sjeb7":"File message","k_0yd2ft8":"Group notification","k_13s7mxn":"Image message","k_13satlt":"Location message","k_00bbtsx":"Combined message","k_13sqwu4":"Voice message","k_13sqjjp":"Video message","k_03iqsh4":" $s to ","k_191t5n4":"$opUserNickName changed ","k_1pg6aoj":"$opUserNickName quit group chat","k_1f6zt3v":"Invite $invitedMemberString to the group","k_0y7zd07":"Remove $invitedMemberString from the group","k_1d5mshh":"User $joinedMemberString joined the group","k_0yenqf0":"$userName was","k_0spotql":"Set $adminMember as admin","k_0pg5zzj":"System message: $operationType","k_1c7z88n":"[File] $fileName","k_1c3us5n":"The current group does not support @all","k_11k579v":"Invalid statements detected","k_0qba4ns":" attempted to access your $yoursItem","k_0oozw9x":"$diffMinutes minutes ago","k_13hzn00":"$yesterday, yesterday","k_0n9pyxz":"The user does not exist","k_1bjwemh":"Search by user ID","k_02owlq8":"My user ID: $userID","k_1wu8h4x":"Me: $showName","k_16758qw":"Add friend","k_1shx4d9":"Status: $selfSignature","k_0i553x0":"Enter verification information","k_031ocwx":"Enter remarks and list","k_003ojje":"Remarks","k_003lsav":"List","k_167bdvq":"My friends","k_156b4ut":"Friend request sent","k_1loix7s":"Group type: $groupType","k_1lqbsib":"The group chat does not exist","k_03h153m":"Search by group ID","k_0oxak3r":"Group request sent","k_1uh417q":"$displayName recalled a message","k_1aszp2k":"Are you sure you want to send the message again?","k_0h1ygf8":"Call initiated","k_0h169j0":"Call canceled","k_0h13jjk":"Call accepted","k_0h19hfx":"Call rejected","k_0obi9lh":"No answer","k_0ohzb9l":"Call duration: $callTime","k_0y9u662":"$appName currently does not support this file type. You can use another app to open and preview the file.","k_1ht1b80":"Receiving","k_0d5z4m5":"Select reminder receiver","k_1665ltg":"Initiate call","k_003kthh":"Photo","k_119ucng":"The image cannot be empty","k_0w9x8gw":"Selected successfully: $successPath","k_1np495n":"$messageString[Someone@me]","k_1m797yi":"$messageString[@all]","k_1uaov41":"Search for chat content","k_0bxm97s":"Admin ($adminNum/10)","k_0jayw3z":"Group members ($groupMemberNum members)","k_0h1svv1":"Delete group member","k_0h1g636":"Add group member","k_01yfa4o":"$memberCount members","k_0hpukyx":"View more group members","k_0qtsar0":"Mute notifications","k_03xd79d":"Status: $signature","k_1m9dftc":"All contacts","k_0em4gyz":"All group chats","k_002twmj":"Group chat","k_09kga0d":"More chat history","k_1ui5lzi":"$count messages are found","k_09khmso":"Related chat records","k_1kevf4k":"Chat history with $receiver","k_03ignw6":"All","k_03icaxo":"Custom","k_1969986":"[Voice Call]:$callingLastMsgShow","k_1960dlr":"[Video Call]:$callingLastMsgShow","k_1qbg9xc":"$option8 to ","k_1wq5ubm":"$option7 changed ","k_0y5pu80":"$option6 quit group chat","k_0nl7cmd":"Invite $option5 to the group","k_1ju5iqw":"Remove $option4 from the group","k_1ovt677":"User $option3 joined the group","k_0k05b8b":"$option2 was ","k_0wm4xeb":"System message: $option2","k_0nbq9v3":"Call duration: $option2","k_0i1kf53":"[File] $option2","k_1gnnby6":" attempted to access your $option2","k_1wh4atg":"$option2 minutes ago","k_07sh7g1":"$option2, yesterday","k_1pj8xzh":"My user ID: $option2","k_0py1evo":"Status: $option2","k_1kvj4i2":"$option2 recalled a message","k_1v0lbpp":"$option2 currently does not support this file type. You can use another app to open and preview the file.","k_0torwfz":"Selected successfully: $option2","k_0i1bjah":"$option1 recalled a message","k_1qzxh9q":"Call duration: $option3","k_0wrgmom":"[Voice Call]:$option1","k_06ix2f0":"[Video Call]:$option2","k_08o3z5w":"[File] $option1","k_0ezbepg":"$option2[Someone@me]","k_1ccnht1":"$option2[@all]","k_1k3arsw":"Admin ($option2/10)","k_1d4golg":"Group members ($option1 members)","k_1bg69nt":"$option1 members","k_00gjqxj":"Status: $option1","k_0c29cxr":"$option1 messages are found","k_1twk5rz":"Chat history with $option1","k_18o68ro":"Allow ","k_1onpf8u":" to access your camera to take photos, record videos, and make video calls.","k_17irga5":" to access your microphone to send voice messages, record videos, and make voice/video calls.","k_0572kc4":" to access your photos to send images and videos.","k_0slykws":" to access your album to save images and videos.","k_119pkcd":" to access your files to view, select and send files in a chat.","k_03c49qt":"Authorize now","k_0nt2uyg":"Back to the bottom","k_04l16at":"$option1 new messages","k_13p3w93":"Someone @ me","k_18w5uk6":"@ all","k_0jmujgh":"You are receiving other files","k_12s5ept":"Message details","k_0mxa4f4":"$option1 read","k_061tue3":"$option2 unread","k_1vn4xq1":"remove $adminMember from admin","k_0e35hsw":"Please allow us to use your camera to capture photos and videos sending to your friends and make video calls.","k_0dj6yr7":"Please allow us to use your microphone for sending voice message, make video/audio calls.","k_003qnsl":"Save","k_0s3rtpw":"Please allow us to access the media and files on your devices, in order to select and send to your friend, or save from them.","k_0tezv85":" Would like to access $option2","k_002rety":" permission. ","k_0gqewd3":"Later","k_03eq4s1":"Authorize Now","k_18qjstb":"Transfer Group","k_0on1aj2":"$option2 messages @ me","k_09j4izl":"[Someone @ me] ","k_1oqtjw0":"[@ all] ","k_1x5a9vb":"This is: $option1","k_14n31e7":"Add Group","k_08nc5j1":"Group type: $option1","k_1josu12":"$option1 group joining request(s)","k_0n2x5s0":"Verification message: $option2","k_03c1nx0":"Agreed","k_03aw9w8":"Rejected","k_038ryos":"Handle now","k_0gw8pum":"Add Group","k_1gcvfrj":"Please fill in the remarks","k_002v9zj":"确认","k_10oqrki":"轻触拍照","k_0f8b3ws":"加载失败","k_11cm5lm":"手动聚焦","k_002uzrd":"预览","k_003qkn3":"录像","k_003k6a7":"拍照","k_0bqpqco":"拍照按钮","k_1626ozl":"停止录像","k_003lvmu":"前置","k_003lued":"后置","k_003lwzh":"外置","k_002qzi3":"关闭","k_003pufb":"自动","k_0apm0ze":"拍照时闪光","k_157zog5":"始终闪光","k_0cfyqhy":"$option1 画面预览","k_0phctlz":"闪光模式: $option2","k_02vfqe0":"切换至 $option3 摄像头","k_0f0y9ex":"说话时间太短","k_0ln70tk":"无法打开URL","k_11a3jdv":"轻触拍照,长按摄像","k_1k18miv":"请传入离开群组生命周期函数,提供返回首页或其他页面的导航方法。","k_1fu9ahv":"全员禁言状态","k_0gmwbnd":"全员禁言中","k_0got2zr":"您被禁言","k_0y9jck8":"你必须自定义search bar,并处理点击跳转","k_0yum3tv":"如使用自定义区域,请在profileWidgetBuilder传入对应组件","k_09kalj0":"清空聊天记录","k_14j5iul":"删除并退出","k_125ru1w":"解散该群","k_0jtutmw":"退出后不会接收到此群聊消息","k_0jtzmqa":"解散后不会接收到此群聊消息","k_0r8fi93":"好友添加成功","k_02qw14e":"好友申请已发出","k_0n3md5x":"当前用户在黑名单","k_094phq4":"好友添加失败","k_129scag":"好友删除成功","k_129uzfn":"好友删除失败","k_1666isy":"清除好友","k_1679vrd":"加为好友","k_1ualc52":"看看对方带来的数据是啥","k_0szluvp":"设置对方在线状态","k_0f4rnf8":"该用户已是好友","k_1tdkom4":"您已是群成员","k_1p2lyuz":"对方正在输入中...","k_1g8wfpy":"...共$option1人","k_12rv9vw":"回应详情","k_0havgi0":"[查看详情 >>](${linkMessage.link})","k_0n9p7g8":"群组不存在","k_1tdh5vn":"您不是群成员","k_0h1q57v":"暂无群成员","k_0y5drq1":"[查看详情 >>]($option1)","k_03pjp61":"[表情消息]","k_1jpvzul":"[自定义消息]","k_03u3bh1":"[文件消息]","k_1odsnsw":"[群消息]","k_03sel4t":"[图片消息]","k_03sfw3r":"[位置消息]","k_03xpuwq":"[合并消息]","k_07ycxwo":"[没有元素]","k_03rc9vz":"[文本消息]","k_046uopf":"[视频消息]","k_0ehmsun":"设备存储空间不足,建议清理,以获得更好使用体验","k_003kmos":"图片","k_002s86q":"视频","k_06bk5ei":"视频消息仅限 mp4 格式","k_13opfxf":"Web网页端不支持搜索","k_1i0o0y2":"暂时仅限 Android/iOS 端","k_045dtzl":"$option1的聊天记录","k_0t0131u":"群资料信息","k_18ok8xz":"消息接收方式","k_03ax3ks":"群资料","k_0sqvoqo":"将 $option1 设置为管理员","k_1gbg1v8":"将 $option1 取消管理员","k_17k64g4":"群聊创建成功!","k_05mn217":"暂未安装表情包插件,如需使用表情相关功能,请根据本文档安装:https://cloud.tencent.com/document/product/269/70746","k_14j17nz":"暂无表情包","k_0fvjexh":"正在下载中","k_1cdagzz":"已加入待下载队列,其他文件下载中","k_0g4vojc":"开始下载","k_1g32es3":"[调皮]@2x.png","k_1g8qorz":"[爱你]@2x.png","k_1g4hmx6":"[爱情]@2x.png","k_1g6b558":"[爱心]@2x.png","k_1g3m4su":"[傲慢]@2x.png","k_1g2jym7":"[白眼]@2x.png","k_0cgkxuw":"[棒棒糖]@2x.png","k_1g48br2":"[抱抱]@2x.png","k_1g49ol8":"[抱拳]@2x.png","k_1g0ras3":"[爆筋]@2x.png","k_1ghy881":"[鄙视]@2x.png","k_1g86bmv":"[闭嘴]@2x.png","k_1g1xs1p":"[鞭炮]@2x.png","k_1g8i6ri":"[便便]@2x.png","k_1g2u5kf":"[擦汗]@2x.png","k_1g60uwh":"[彩带]@2x.png","k_1g1o0d0":"[彩球]@2x.png","k_1g6a6yq":"[菜刀]@2x.png","k_1g6vqo2":"[差劲]@2x.png","k_1g0kvjc":"[钞票]@2x.png","k_1g65x7e":"[车厢]@2x.png","k_0e1tjol":"[打哈欠]@2x.png","k_1g65n58":"[大兵]@2x.png","k_1g7se7o":"[大哭]@2x.png","k_1g03868":"[蛋糕]@2x.png","k_1h8nm66":"[刀]@2x.png","k_1g3dlpi":"[得意]@2x.png","k_1g3u434":"[灯泡]@2x.png","k_1giuqs7":"[凋谢]@2x.png","k_1g8r0r9":"[多云]@2x.png","k_1g7k6i1":"[发呆]@2x.png","k_1g44zsp":"[发抖]@2x.png","k_1g5l96i":"[飞机]@2x.png","k_1g7wsqj":"[飞吻]@2x.png","k_1g49luq":"[奋斗]@2x.png","k_1gixbsm":"[风车]@2x.png","k_1g6cqbq":"[尴尬]@2x.png","k_1g6jbw5":"[勾引]@2x.png","k_1g3lwo1":"[鼓掌]@2x.png","k_1g13nkj":"[害羞]@2x.png","k_1g0mt47":"[憨笑]@2x.png","k_0bxujkf":"[红灯笼]@2x.png","k_0hhaeh8":"[红双喜]@2x.png","k_1g0jnts":"[坏笑]@2x.png","k_1g46g9c":"[挥手]@2x.png","k_1g4vi9g":"[回头]@2x.png","k_1gf7hes":"[饥饿]@2x.png","k_1g6mvsm":"[激动]@2x.png","k_1gku5mf":"[街舞]@2x.png","k_1g4hidg":"[惊恐]@2x.png","k_1gjbrtu":"[惊讶]@2x.png","k_1g6sand":"[咖啡]@2x.png","k_1g4s8rj":"[磕头]@2x.png","k_1g1wn34":"[可爱]@2x.png","k_1g3l0wd":"[可怜]@2x.png","k_1ggaon9":"[抠鼻]@2x.png","k_1ggvcb0":"[骷髅]@2x.png","k_1h8yqjt":"[酷]@2x.png","k_0jac97i":"[快哭了]@2x.png","k_1h8oiby":"[困]@2x.png","k_1g0s5hg":"[蜡烛]@2x.png","k_1g1iuer":"[篮球]@2x.png","k_1g2xjfi":"[冷汗]@2x.png","k_0s5oyqw":"[礼品袋]@2x.png","k_1g1qqvf":"[礼物]@2x.png","k_1g2slew":"[流汗]@2x.png","k_1g3z9xx":"[流泪]@2x.png","k_1g6pabn":"[麻将]@2x.png","k_0pkaxul":"[麦克风]@2x.png","k_1g7m0zj":"[猫咪]@2x.png","k_0ibvtpo":"[么么哒]@2x.png","k_1g1hoh1":"[玫瑰]@2x.png","k_1gfzeow":"[米饭]@2x.png","k_1g5l15p":"[面条]@2x.png","k_1g2hfa6":"[奶瓶]@2x.png","k_1gix9pj":"[难过]@2x.png","k_1giqn6g":"[闹钟]@2x.png","k_1h8kd64":"[怒]@2x.png","k_1g0vui9":"[怄火]@2x.png","k_1g1jsj7":"[皮球]@2x.png","k_1ghdluw":"[啤酒]@2x.png","k_1gl6ec7":"[瓢虫]@2x.png","k_1g7gg5p":"[撇嘴]@2x.png","k_1g8psin":"[乒乓]@2x.png","k_1gjzu3p":"[汽车]@2x.png","k_1h8mr0k":"[强]@2x.png","k_1g45y2n":"[敲打]@2x.png","k_1gkaxsl":"[青蛙]@2x.png","k_0jcfnoo":"[糗大了]@2x.png","k_1g4njy1":"[拳头]@2x.png","k_1h8mqr3":"[弱]@2x.png","k_1h926fg":"[色]@2x.png","k_1g6rtbq":"[沙发]@2x.png","k_1giirh6":"[删除]@2x.png","k_1g14ny9":"[闪电]@2x.png","k_1g6bmsr":"[胜利]@2x.png","k_1g1rytx":"[示爱]@2x.png","k_1g52fbz":"[手枪]@2x.png","k_1h90dam":"[衰]@2x.png","k_1gigiae":"[睡觉]@2x.png","k_1gijchz":"[太阳]@2x.png","k_1g1sgji":"[跳绳]@2x.png","k_1gjwuri":"[跳跳]@2x.png","k_1g0juhk":"[偷笑]@2x.png","k_1h8nzla":"[吐]@2x.png","k_1g6cv0i":"[委屈]@2x.png","k_1g46l5g":"[握手]@2x.png","k_1g2pgkd":"[西瓜]@2x.png","k_1ging9p":"[下雨]@2x.png","k_1h8nzil":"[吓]@2x.png","k_1g7q7wr":"[献吻]@2x.png","k_1gl6uum":"[香蕉]@2x.png","k_1g23fys":"[象棋]@2x.png","k_0j75rdh":"[心碎了]@2x.png","k_1g6ajj2":"[信封]@2x.png","k_1g21prz":"[熊猫]@2x.png","k_1h8octi":"[嘘]@2x.png","k_1h91zox":"[药]@2x.png","k_1ghttfl":"[疑问]@2x.png","k_1ghk7sz":"[阴险]@2x.png","k_0gl37zz":"[右车头]@2x.png","k_0ifkj1p":"[右哼哼]@2x.png","k_0g1yh2e":"[右太极]@2x.png","k_1g9dkfc":"[雨伞]@2x.png","k_1g8jl88":"[月亮]@2x.png","k_1h8lhqj":"[晕]@2x.png","k_1gi9x2q":"[再见]@2x.png","k_1g6dwwv":"[炸弹]@2x.png","k_1fzmkfi":"[折磨]@2x.png","k_1g6jbiw":"[纸巾]@2x.png","k_1ggjnwu":"[咒骂]@2x.png","k_1g4qlq8":"[猪头]@2x.png","k_1g1lqzz":"[抓狂]@2x.png","k_1g80j3u":"[转圈]@2x.png","k_1g0z55s":"[龇牙]@2x.png","k_1g3ju6v":"[钻戒]@2x.png","k_0gl51l6":"[左车头]@2x.png","k_0iflllk":"[左哼哼]@2x.png","k_0g1y3ir":"[左太极]@2x.png","k_026hiq5":"消息列表加载中","k_003tu8k":"爱你","k_003myvp":"傲慢","k_003kddw":"白眼","k_039yfhv":"棒棒糖","k_003nu3p":"抱抱","k_003nijr":"抱拳","k_003mg88":"爆筋","k_002v17e":"鄙视","k_003qhy4":"闭嘴","k_003l5fq":"鞭炮","k_003uacl":"便便","k_003oq1g":"擦汗","k_003qvey":"彩带","k_003jci7":"彩球","k_003pyu1":"菜刀","k_003q97d":"差劲","k_003po5d":"车厢","k_03eadb2":"打哈欠","k_003pnuf":"大兵","k_003kg57":"蛋糕","k_003mxkt":"得意","k_003onu3":"灯泡","k_002uv8s":"凋谢","k_003kqy0":"调皮","k_003tyum":"多云","k_003pv9u":"发呆","k_036o6mu":"发抖t","k_003nogx":"飞机","k_003q7wg":"飞吻","k_003m0jd":"奋斗","k_002ult9":"风车","k_003r8gt":"尴尬","k_003qy4u":"勾引","k_003mnoa":"鼓掌","k_003lmw8":"害羞","k_003mb30":"憨笑","k_03bj41g":"红灯笼","k_03dxw2f":"红双喜","k_003mk57":"坏笑","k_003nmvf":"挥手","k_003r2i7":"回头","k_002s6f3":"饥饿","k_003qd0t":"激动","k_002vgi4":"街舞","k_003nz33":"惊恐","k_002wh4p":"惊讶","k_003ozpu":"咖啡","k_003qvs4":"磕头","k_003l3wb":"可爱","k_003nuwm":"可怜","k_002rw1q":"抠鼻","k_002tujb":"骷髅","k_00030eq":"酷","k_03i8ath":"快哭了","k_000421h":"困","k_003l5i7":"蜡烛","k_003j72g":"篮球","k_003ofwl":"冷汗","k_02mw65v":"礼品袋","k_003ku40":"礼物","k_003ookz":"流汗","k_003on72":"流泪","k_003rjy0":"麻将","k_003q2f8":"猫咪","k_03et393":"么么哒","k_003j7j2":"玫瑰","k_002sr0b":"米饭","k_003nnza":"面条","k_003jef9":"奶瓶","k_002umn0":"难过","k_002rjib":"闹钟","k_0003zcn":"怒","k_003jzwq":"怄火","k_003j4js":"皮球","k_002r5ir":"啤酒","k_002ubu4":"瓢虫","k_003ppo6":"撇嘴","k_003ty3o":"乒乓","k_002vxwe":"汽车","k_00043hb":"强","k_003nmbo":"敲打","k_002tfhq":"青蛙","k_03i7lrn":"糗大了","k_003r03m":"拳头","k_00043h0":"弱","k_000345z":"色","k_003qmp9":"沙发","k_003it8a":"闪电","k_003pxow":"胜利","k_003kw8e":"示爱","k_003n99g":"手枪","k_00035cl":"衰","k_002vl3h":"睡觉","k_002rgqk":"太阳","k_003m9d1":"跳绳","k_002vobp":"跳跳","k_003mkoz":"偷笑","k_00041px":"吐","k_003rjh5":"委屈","k_003j36u":"西瓜","k_002re92":"下雨","k_00041py":"吓","k_003q06o":"献吻","k_002ubjp":"香蕉","k_003o2tr":"象棋","k_03ie6pa":"心碎了","k_003rao5":"信封","k_003l3us":"熊猫","k_000424d":"嘘","k_00033yi":"药","k_002qtyy":"疑问","k_002qe0o":"阴险","k_03gu7us":"右车头","k_03ere8m":"右哼哼","k_003uqk3":"雨伞","k_003tzdv":"月亮","k_0003z00":"晕","k_002vdrd":"再见","k_003ra1w":"炸弹","k_003lcad":"折磨","k_003q7sz":"纸巾","k_002thn9":"咒骂","k_003qx7f":"猪头","k_003l044":"抓狂","k_003qg4h":"转圈","k_003kb97":"龇牙","k_03gu53l":"左车头","k_03erd1f":"左哼哼","k_003nyvl":"爱情","k_003r85z":"爱心","k_003mk8j":"钞票","k_003pwfj":"大哭","k_00042w5":"刀","k_003nmtr":"握手","k_03c529p":"右太极","k_003n4mk":"钻戒","k_03c5488":"左太极","k_1llp7tu":"该用户不存在","k_0tbyqyb":"加载中…","k_0td1p3f":"保存中…","k_1klqdh1":"仅限汉字、英文、数字和下划线","k_03el5lp":"未填写","k_1ui0gai":"搜索指定内容","k_003nvk2":"消息","k_03agld7":"群提示","k_0elt0kw":"添加群聊","k_0s3sgel":"移出黑名单","k_1qqgjra":"$option3条未读消息","k_0uubyjr":"以下为未读消息","k_16as7eq":"表情回应","k_003s12u":"回复","k_003s38r":"更多","k_002wkr3":"翻译","k_13g4hxv":"翻译完成","k_003molk":"表情","k_165bbw6":"消息历史","k_13sqc0z":"清除消息","k_0glns86":"删除会话","k_13s99rx":"清空消息","k_11vsa3j":"退出群组","k_11vvszp":"解散群组","k_15i9w72":"群管理员","k_0p3espj":"设置备注名","k_118sw9v":"立即搜索","k_0h20hg5":"视频通话","k_0h22snw":"语音通话","k_003lz6t":"对方","k_1xf4yre":"发送给$option1","k_003por5":"截图","k_1rw7s82":" 访问相册中视频权限,以正常使用发送视频等功能。","k_003rcwm":"打开","k_1698c42":"在访达中打开","k_066fxsz":"查看文件夹","k_0k432y2":"无法发送,包含文件夹","k_002wb4y":"会话"} \ No newline at end of file diff --git a/lib/i18n/strings_zh-Hans.i18n.json b/lib/i18n/strings_zh-Hans.i18n.json index 72463e1..5a79486 100644 --- a/lib/i18n/strings_zh-Hans.i18n.json +++ b/lib/i18n/strings_zh-Hans.i18n.json @@ -659,8 +659,34 @@ "k_1ui0gai": "搜索指定内容", "k_003nvk2": "消息", "k_03agld7": "群提示", + "k_0elt0kw": "添加群聊", + "k_0s3sgel": "移出黑名单", + "k_1qqgjra": "$option3条未读消息", + "k_0uubyjr": "以下为未读消息", + "k_16as7eq": "表情回应", + "k_003s12u": "回复", + "k_003s38r": "更多", "k_002wkr3": "翻译", "k_13g4hxv": "翻译完成", - "k_1qqgjra": "$option3条未读消息", - "k_0uubyjr": "以下为未读消息" + "k_003molk": "表情", + "k_165bbw6": "消息历史", + "k_13sqc0z": "清除消息", + "k_0glns86": "删除会话", + "k_13s99rx": "清空消息", + "k_11vsa3j": "退出群组", + "k_11vvszp": "解散群组", + "k_15i9w72": "群管理员", + "k_0p3espj": "设置备注名", + "k_118sw9v": "立即搜索", + "k_0h20hg5": "视频通话", + "k_0h22snw": "语音通话", + "k_003lz6t": "对方", + "k_1xf4yre": "发送给$option1", + "k_003por5": "截图", + "k_1rw7s82": " 访问相册中视频权限,以正常使用发送视频等功能。", + "k_003rcwm": "打开", + "k_1698c42": "在访达中打开", + "k_066fxsz": "查看文件夹", + "k_0k432y2": "无法发送,包含文件夹", + "k_002wb4y": "会话" } \ No newline at end of file diff --git a/lib/i18n/strings_zh-Hant.i18n.json b/lib/i18n/strings_zh-Hant.i18n.json index d36d77a..0c8ea1c 100644 --- a/lib/i18n/strings_zh-Hant.i18n.json +++ b/lib/i18n/strings_zh-Hant.i18n.json @@ -1 +1 @@ -{"k_1yemzyd":"收到一條訊息","k_0ylosxn":"自定義訊息","k_13sajrj":"貼圖訊息","k_13sjeb7":"檔案訊息","k_0yd2ft8":"群提示訊息","k_13s7mxn":"圖片訊息","k_13satlt":"位置訊息","k_00bbtsx":"合並轉發訊息","k_13sqwu4":"語音訊息","k_13sqjjp":"影片","k_1fdhj9g":"該版本不支持此訊息","k_06pujtm":"同意任何用戶添加好友","k_0gyhkp5":"需要驗證","k_121ruco":"拒絕任何人加好友","k_05nspni":"自定義字段","k_03fchyy":"群頭像","k_03i9mfe":"群簡介","k_03agq58":"群名稱","k_039xqny":"群通知","k_003tr0a":"群主","k_03iqsh4":"$s為 ","k_191t5n4":"$opUserNickName修改","k_1pg6aoj":"$opUserNickName退出群組","k_1f6zt3v":"邀請$invitedMemberString加入群組","k_0y7zd07":"將$invitedMemberString踢出群組","k_03c49qt":"去授權","k_1d5mshh":"用戶$joinedMemberString加入了群組","k_002wddw":"禁言","k_0got6f7":"解除禁言","k_0yenqf0":"$userName 被","k_0spotql":"將 $adminMember 設置為管理員","k_0pg5zzj":"系統訊息 $operationType","k_0ohzb9l":"通話時間:$callTime","k_1uaqed6":"[自定義]","k_0z2z7rx":"[語音]","k_0y39ngu":"[貼圖]","k_1c7z88n":"[檔案] $fileName","k_0y1a2my":"[圖片]","k_0z4fib8":"[影片]","k_0y24mcg":"[位置]","k_0pewpd1":"[聊天記錄]","k_13s8d9p":"未知訊息","k_1c3us5n":"當前群組不支持@全體成員","k_11k579v":"發言中有非法語句","k_003qkx2":"日歷","k_003n2pz":"相機","k_03idjo0":"聯絡人","k_003ltgm":"位置","k_02k3k86":"咪高風","k_003pm7l":"相冊","k_15ao57x":"相冊寫入","k_164m3jd":"本地存儲","k_0qba4ns":"想訪問您的$yoursItem","k_03r6qyx":"我們需要您的同意才能獲取信息","k_02noktt":"不允許","k_00043x4":"好","k_003qzac":"昨天","k_003r39d":"前天","k_03fqp9o":"星期天","k_03ibg5h":"星期一","k_03i7hu1":"星期二","k_03iaiks":"星期三","k_03el9pa":"星期四","k_03i7ok1":"星期五","k_03efxyg":"星期六","k_0oozw9x":"$diffMinutes 分鐘前","k_003q7ba":"下午","k_003q7bb":"上午","k_003pu3h":"現在","k_13hzn00":"昨天 $yesterday","k_0n9pyxz":"用戶不存在","k_1bjwemh":"搜尋用戶 ID","k_003kv3v":"搜尋","k_02owlq8":"我的用戶ID: $userID","k_1wu8h4x":"我是: $showName","k_16758qw":"添加好友","k_1shx4d9":"個性簽名: $selfSignature","k_0i553x0":"填寫驗證信息","k_031ocwx":"請填寫備註和分組","k_003ojje":"備註","k_003lsav":"分組","k_167bdvq":"我的好友","k_156b4ut":"好友申請已發送","k_002r305":"發送","k_03gu05e":"聊天室","k_03b4f3p":"會議群","k_03avj1p":"公開群","k_03asq2g":"工作群","k_03b3hbi":"未知群","k_1loix7s":"群類型: $groupType","k_1lqbsib":"該群組不存在","k_03h153m":"搜尋群ID","k_0oxak3r":"群申請已發送","k_002rflt":"刪除","k_1don84v":"無法定位到原訊息","k_003q5fi":"復製","k_003prq0":"轉發","k_002r1h2":"多選","k_003j708":"引用","k_003pqpr":"回收","k_03ezhho":"已復製","k_11ctfsz":"暫未實現","k_1hbjg5g":"[群系統訊息]","k_03tvswb":"[未知訊息]","k_155cj23":"您回收了一條訊息,","k_0gapun3":"重新編輯","k_1uh417q":"$displayName回收了一條訊息","k_1aszp2k":"您確定要重發這條訊息麽?","k_003rzap":"確定","k_003nevv":"取消","k_0003z7x":"您","k_002wfe4":"已讀","k_002wjlg":"未讀","k_0h1ygf8":"發起通話","k_0h169j0":"取消通話","k_0h13jjk":"接受通話","k_0h19hfx":"拒絕通話","k_0obi9lh":"超時未接聽","k_0y9u662":"「$appName」暫不可以開啟此類檔案,你可以使用其他應用開啟並預覽","k_001nmhu":"用其他應用開啟","k_1ht1b80":"正在接收中","k_105682d":"圖片載入失敗","k_0pytyeu":"圖片保存成功","k_0akceel":"圖片保存失敗","k_003rk1s":"保存","k_04a0awq":"[語音訊息]","k_105c3y3":"影片載入失敗","k_176rzr7":"聊天記錄","k_0d5z4m5":"選擇提醒人","k_003ngex":"完成","k_1665ltg":"發起呼叫","k_003n8b0":"拍攝","k_003kthh":"照片","k_003tnp0":"檔案","k_0jhdhtp":"發送失敗,影片不能大於100MB","k_119ucng":"圖片不能為空","k_0w9x8gw":"選擇成功$successPath","k_13dsw4l":"松開取消","k_0am7r68":"手指上滑,取消發送","k_15jl6qw":"說話時間太短!","k_0gx7vl6":"按住說話","k_15dlafd":"逐條轉發","k_15dryxy":"合並轉發","k_1eyhieh":"確定刪除已選訊息","k_17fmlyf":"清除聊天","k_0dhesoz":"取消置頂","k_002sk7x":"置頂","k_003ll77":"草稿","k_03icaxo":"自定義","k_1969986":"[語音通話]:$callingLastMsgShow","k_1960dlr":"[視訊通話]:$callingLastMsgShow","k_1np495n":"$messageString[有人@我]","k_1m797yi":"$messageString[@所有人]","k_1uaov41":"查找聊天內容","k_003kfai":"未知","k_13dq4an":"自動審批","k_0l13cde":"管理員審批","k_11y8c6a":"禁止加群","k_1kvyskd":"無網絡連接,無法修改","k_16payqf":"加群方式","k_0vzvn8r":"修改群名稱","k_038lh6u":"群管理","k_0k5wyiy":"設置管理員","k_0goiuwk":"全員禁言","k_1g889xx":"全員禁言開啟後,只允許群主和管理員發言。","k_0wlrefq":"添加需要禁言的群成員","k_0goox5g":"設置禁言","k_08daijh":"成功取消管理員身份","k_0bxm97s":"管理員 ($adminNum/10)","k_0k5u935":"添加管理員","k_03enyx5":"群成員","k_0jayw3z":"群成員($groupMemberNum人)","k_0h1svv1":"刪除群成員","k_0h1g636":"添加群成員","k_0uj7208":"無網絡連接,無法查看群成員","k_01yfa4o":"$memberCount人","k_0hpukyx":"查看更多群成員","k_0qtsar0":"訊息免打擾","k_0ef2a12":"修改我的群昵稱","k_1aajych":"僅限中文、字母、數字和下劃線,2-20個字","k_137pab5":"我的群昵稱","k_0ivim6d":"暫無群公告","k_03eq6cn":"群公告","k_002vxya":"編輯","k_17fpl3y":"置頂聊天","k_03es1ox":"群類型","k_003mz1i":"同意","k_003lpre":"拒絕","k_003qk66":"頭像","k_003lhvk":"昵稱","k_003ps50":"賬號","k_15lx52z":"個性簽名","k_003qgkp":"性別","k_003m6hr":"生日","k_0003v6a":"男","k_00043x2":"女","k_03bcjkv":"未設置","k_11s0gdz":"修改昵稱","k_0p3j4sd":"僅限中字、字母、數字和下劃線","k_15lyvdt":"修改簽名","k_0vylzjp":"這個人很懶,什麽也沒寫","k_1hs7ese":"等上線再改這個","k_03exjk7":"備註名","k_0s3skfd":"加入黑名單","k_0p3b31s":"修改備註名","k_0003y9x":"無","k_11zgnfs":"個人資料","k_03xd79d":"個性簽名: $signature","k_1tez2xl":"暫無個性簽名","k_118prbn":"全局搜尋","k_1m9dftc":"全部聯絡人","k_0em4gyz":"全部群組","k_002twmj":"群組","k_09kga0d":"更多聊天記錄","k_1ui5lzi":"$count條相關聊天記錄","k_09khmso":"相關聊天記錄","k_1kevf4k":"與$receiver的聊天記錄","k_0vjj2kp":"群組的聊天記錄","k_003n2rp":"選擇","k_03ignw6":"所有人","k_03erpei":"管理員","k_0qi9tno":"群主、管理員","k_1m9exwh":"最近聯絡人","k_119nwqr":"輸入不能為空","k_0pzwbmg":"影片保存成功","k_0aktupv":"影片保存失敗","k_1qbg9xc":"$option8為 ","k_1wq5ubm":"$option7修改","k_0y5pu80":"$option6退出群組","k_0nl7cmd":"邀請$option5加入群組","k_1ju5iqw":"將$option4踢出群組","k_1ovt677":"用戶$option3加入了群組","k_0k05b8b":"$option2 被","k_0wm4xeb":"系統訊息 $option2","k_0nbq9v3":"通話時間:$option2","k_0i1kf53":"[檔案] $option2","k_1gnnby6":"想訪問您的$option2","k_1wh4atg":"$option2 分鐘前","k_07sh7g1":"昨天 $option2","k_1pj8xzh":"我的用戶ID: $option2","k_0py1evo":"個性簽名: $option2","k_1kvj4i2":"$option2回收了一條訊息","k_1v0lbpp":"「$option2」暫不可以開啟此類檔案,你可以使用其他應用開啟並預覽","k_0torwfz":"選擇成功$option2","k_0i1bjah":"$option1回收了一條訊息","k_1qzxh9q":"通話時間:$option3","k_0wrgmom":"[語音通話]:$option1","k_06ix2f0":"[視訊通話]:$option2","k_08o3z5w":"[檔案] $option1","k_0ezbepg":"$option2[有人@我]","k_1ccnht1":"$option2[@所有人]","k_1k3arsw":"管理員 ($option2/10)","k_1d4golg":"群成員($option1人)","k_1bg69nt":"$option1人","k_00gjqxj":"個性簽名: $option1","k_0c29cxr":"$option1條相關聊天記錄","k_1twk5rz":"與$option1的聊天記錄","k_1vn4xq1":"將 $adminMember 取消管理員","k_0e35hsw":"為方便您將所拍攝的照片或影片發送給朋友,以及進行視訊通話,請允許我們訪問攝像頭進行拍攝照片和影片。","k_0dj6yr7":"為方便您發送語音訊息、拍攝影片以及音視訊通話,請允許我們使用咪高風進行錄音。","k_003qnsl":"存儲","k_0s3rtpw":"為方便您查看和選擇相冊裏的圖片影片發送給朋友,以及保存內容到設備,請允許我們訪問您設備上的照片、媒體內容。","k_0tezv85":" 申請獲取$option2","k_002rety":"權限","k_18o68ro":"需要授予","k_1onpf8u":" 相機權限,以正常使用拍攝圖片/影片、視訊通話等功能。","k_17irga5":" 咪高風權限,以正常使用發送語音訊息、拍攝影片、音視訊通話等功能。","k_0572kc4":" 訪問照片權限,以正常使用發送圖片、影片等功能。","k_0slykws":" 訪問相冊寫入權限,以正常使用存儲圖片、影片等功能。","k_119pkcd":" 檔案讀寫權限,以正常使用在聊天功能中的圖片查看、選擇能力和發送檔案的能力。","k_0gqewd3":"以後再說","k_03eq4s1":"去開啟","k_0nt2uyg":"回到最新位置","k_04l16at":"$option1條新訊息","k_13p3w93":"有人@我","k_18w5uk6":"@所有人","k_0jmujgh":"其他檔案正在接收中","k_12s5ept":"訊息詳情","k_0mxa4f4":"$option1人已讀","k_061tue3":"$option2人未讀","k_18qjstb":"轉讓群主","k_0on1aj2":"有$option2條@我訊息","k_09j4izl":"[有人@我] ","k_1oqtjw0":"[@所有人] ","k_1x5a9vb":"我是: $option1","k_14n31e7":"進群請求","k_08nc5j1":"群類型: $option1","k_1josu12":"$option1 條入群請求","k_0n2x5s0":"驗證消息: $option2","k_03c1nx0":"已同意","k_03aw9w8":"已拒絕","k_038ryos":"去處理","k_0gw8pum":"進群申請","k_1gcvfrj":"請填寫備註名","k_002v9zj":"确认","k_10oqrki":"轻触拍照","k_0f8b3ws":"加载失败","k_11cm5lm":"手动聚焦","k_002uzrd":"预览","k_003qkn3":"录像","k_003k6a7":"拍照","k_0bqpqco":"拍照按钮","k_1626ozl":"停止录像","k_003lvmu":"前置","k_003lued":"后置","k_003lwzh":"外置","k_002qzi3":"关闭","k_003pufb":"自动","k_0apm0ze":"拍照时闪光","k_157zog5":"始终闪光","k_0cfyqhy":"$option1 画面预览","k_0phctlz":"闪光模式: $option2","k_02vfqe0":"切换至 $option3 摄像头","k_0f0y9ex":"说话时间太短","k_0ln70tk":"无法打开URL","k_11a3jdv":"轻触拍照,长按摄像","k_1k18miv":"请传入离开群组生命周期函数,提供返回首页或其他页面的导航方法。","k_1fu9ahv":"全员禁言状态","k_0gmwbnd":"全员禁言中","k_0got2zr":"您被禁言","k_0y9jck8":"你必须自定义search bar,并处理点击跳转","k_0yum3tv":"如使用自定义区域,请在profileWidgetBuilder传入对应组件","k_09kalj0":"清空聊天记录","k_14j5iul":"删除并退出","k_125ru1w":"解散该群","k_0jtutmw":"退出后不会接收到此群聊消息","k_0jtzmqa":"解散后不会接收到此群聊消息","k_0r8fi93":"好友添加成功","k_02qw14e":"好友申请已发出","k_0n3md5x":"当前用户在黑名单","k_094phq4":"好友添加失败","k_129scag":"好友删除成功","k_129uzfn":"好友删除失败","k_1666isy":"清除好友","k_1679vrd":"加为好友","k_1ualc52":"看看对方带来的数据是啥","k_0szluvp":"设置对方在线状态","k_0f4rnf8":"该用户已是好友","k_1tdkom4":"您已是群成员","k_1p2lyuz":"对方正在输入中...","k_1g8wfpy":"...共$option1人","k_12rv9vw":"回应详情","k_0havgi0":"[查看详情 >>](${linkMessage.link})","k_0n9p7g8":"群组不存在","k_1tdh5vn":"您不是群成员","k_0h1q57v":"暂无群成员","k_0y5drq1":"[查看详情 >>]($option1)","k_03pjp61":"[表情消息]","k_1jpvzul":"[自定义消息]","k_03u3bh1":"[文件消息]","k_1odsnsw":"[群消息]","k_03sel4t":"[图片消息]","k_03sfw3r":"[位置消息]","k_03xpuwq":"[合并消息]","k_07ycxwo":"[没有元素]","k_03rc9vz":"[文本消息]","k_046uopf":"[视频消息]","k_0ehmsun":"设备存储空间不足,建议清理,以获得更好使用体验","k_003kmos":"图片","k_002s86q":"视频","k_06bk5ei":"视频消息仅限 mp4 格式","k_13opfxf":"Web网页端不支持搜索","k_1i0o0y2":"暂时仅限 Android/iOS 端","k_045dtzl":"$option1的聊天记录","k_0t0131u":"群资料信息","k_18ok8xz":"消息接收方式","k_03ax3ks":"群资料","k_0sqvoqo":"将 $option1 设置为管理员","k_1gbg1v8":"将 $option1 取消管理员","k_17k64g4":"群聊创建成功!","k_05mn217":"暂未安装表情包插件,如需使用表情相关功能,请根据本文档安装:https://cloud.tencent.com/document/product/269/70746","k_14j17nz":"暂无表情包","k_0fvjexh":"正在下载中","k_1cdagzz":"已加入待下载队列,其他文件下载中","k_0g4vojc":"开始下载","k_1g32es3":"[调皮]@2x.png","k_1g8qorz":"[爱你]@2x.png","k_1g4hmx6":"[爱情]@2x.png","k_1g6b558":"[爱心]@2x.png","k_1g3m4su":"[傲慢]@2x.png","k_1g2jym7":"[白眼]@2x.png","k_0cgkxuw":"[棒棒糖]@2x.png","k_1g48br2":"[抱抱]@2x.png","k_1g49ol8":"[抱拳]@2x.png","k_1g0ras3":"[爆筋]@2x.png","k_1ghy881":"[鄙视]@2x.png","k_1g86bmv":"[闭嘴]@2x.png","k_1g1xs1p":"[鞭炮]@2x.png","k_1g8i6ri":"[便便]@2x.png","k_1g2u5kf":"[擦汗]@2x.png","k_1g60uwh":"[彩带]@2x.png","k_1g1o0d0":"[彩球]@2x.png","k_1g6a6yq":"[菜刀]@2x.png","k_1g6vqo2":"[差劲]@2x.png","k_1g0kvjc":"[钞票]@2x.png","k_1g65x7e":"[车厢]@2x.png","k_0e1tjol":"[打哈欠]@2x.png","k_1g65n58":"[大兵]@2x.png","k_1g7se7o":"[大哭]@2x.png","k_1g03868":"[蛋糕]@2x.png","k_1h8nm66":"[刀]@2x.png","k_1g3dlpi":"[得意]@2x.png","k_1g3u434":"[灯泡]@2x.png","k_1giuqs7":"[凋谢]@2x.png","k_1g8r0r9":"[多云]@2x.png","k_1g7k6i1":"[发呆]@2x.png","k_1g44zsp":"[发抖]@2x.png","k_1g5l96i":"[飞机]@2x.png","k_1g7wsqj":"[飞吻]@2x.png","k_1g49luq":"[奋斗]@2x.png","k_1gixbsm":"[风车]@2x.png","k_1g6cqbq":"[尴尬]@2x.png","k_1g6jbw5":"[勾引]@2x.png","k_1g3lwo1":"[鼓掌]@2x.png","k_1g13nkj":"[害羞]@2x.png","k_1g0mt47":"[憨笑]@2x.png","k_0bxujkf":"[红灯笼]@2x.png","k_0hhaeh8":"[红双喜]@2x.png","k_1g0jnts":"[坏笑]@2x.png","k_1g46g9c":"[挥手]@2x.png","k_1g4vi9g":"[回头]@2x.png","k_1gf7hes":"[饥饿]@2x.png","k_1g6mvsm":"[激动]@2x.png","k_1gku5mf":"[街舞]@2x.png","k_1g4hidg":"[惊恐]@2x.png","k_1gjbrtu":"[惊讶]@2x.png","k_1g6sand":"[咖啡]@2x.png","k_1g4s8rj":"[磕头]@2x.png","k_1g1wn34":"[可爱]@2x.png","k_1g3l0wd":"[可怜]@2x.png","k_1ggaon9":"[抠鼻]@2x.png","k_1ggvcb0":"[骷髅]@2x.png","k_1h8yqjt":"[酷]@2x.png","k_0jac97i":"[快哭了]@2x.png","k_1h8oiby":"[困]@2x.png","k_1g0s5hg":"[蜡烛]@2x.png","k_1g1iuer":"[篮球]@2x.png","k_1g2xjfi":"[冷汗]@2x.png","k_0s5oyqw":"[礼品袋]@2x.png","k_1g1qqvf":"[礼物]@2x.png","k_1g2slew":"[流汗]@2x.png","k_1g3z9xx":"[流泪]@2x.png","k_1g6pabn":"[麻将]@2x.png","k_0pkaxul":"[麦克风]@2x.png","k_1g7m0zj":"[猫咪]@2x.png","k_0ibvtpo":"[么么哒]@2x.png","k_1g1hoh1":"[玫瑰]@2x.png","k_1gfzeow":"[米饭]@2x.png","k_1g5l15p":"[面条]@2x.png","k_1g2hfa6":"[奶瓶]@2x.png","k_1gix9pj":"[难过]@2x.png","k_1giqn6g":"[闹钟]@2x.png","k_1h8kd64":"[怒]@2x.png","k_1g0vui9":"[怄火]@2x.png","k_1g1jsj7":"[皮球]@2x.png","k_1ghdluw":"[啤酒]@2x.png","k_1gl6ec7":"[瓢虫]@2x.png","k_1g7gg5p":"[撇嘴]@2x.png","k_1g8psin":"[乒乓]@2x.png","k_1gjzu3p":"[汽车]@2x.png","k_1h8mr0k":"[强]@2x.png","k_1g45y2n":"[敲打]@2x.png","k_1gkaxsl":"[青蛙]@2x.png","k_0jcfnoo":"[糗大了]@2x.png","k_1g4njy1":"[拳头]@2x.png","k_1h8mqr3":"[弱]@2x.png","k_1h926fg":"[色]@2x.png","k_1g6rtbq":"[沙发]@2x.png","k_1giirh6":"[删除]@2x.png","k_1g14ny9":"[闪电]@2x.png","k_1g6bmsr":"[胜利]@2x.png","k_1g1rytx":"[示爱]@2x.png","k_1g52fbz":"[手枪]@2x.png","k_1h90dam":"[衰]@2x.png","k_1gigiae":"[睡觉]@2x.png","k_1gijchz":"[太阳]@2x.png","k_1g1sgji":"[跳绳]@2x.png","k_1gjwuri":"[跳跳]@2x.png","k_1g0juhk":"[偷笑]@2x.png","k_1h8nzla":"[吐]@2x.png","k_1g6cv0i":"[委屈]@2x.png","k_1g46l5g":"[握手]@2x.png","k_1g2pgkd":"[西瓜]@2x.png","k_1ging9p":"[下雨]@2x.png","k_1h8nzil":"[吓]@2x.png","k_1g7q7wr":"[献吻]@2x.png","k_1gl6uum":"[香蕉]@2x.png","k_1g23fys":"[象棋]@2x.png","k_0j75rdh":"[心碎了]@2x.png","k_1g6ajj2":"[信封]@2x.png","k_1g21prz":"[熊猫]@2x.png","k_1h8octi":"[嘘]@2x.png","k_1h91zox":"[药]@2x.png","k_1ghttfl":"[疑问]@2x.png","k_1ghk7sz":"[阴险]@2x.png","k_0gl37zz":"[右车头]@2x.png","k_0ifkj1p":"[右哼哼]@2x.png","k_0g1yh2e":"[右太极]@2x.png","k_1g9dkfc":"[雨伞]@2x.png","k_1g8jl88":"[月亮]@2x.png","k_1h8lhqj":"[晕]@2x.png","k_1gi9x2q":"[再见]@2x.png","k_1g6dwwv":"[炸弹]@2x.png","k_1fzmkfi":"[折磨]@2x.png","k_1g6jbiw":"[纸巾]@2x.png","k_1ggjnwu":"[咒骂]@2x.png","k_1g4qlq8":"[猪头]@2x.png","k_1g1lqzz":"[抓狂]@2x.png","k_1g80j3u":"[转圈]@2x.png","k_1g0z55s":"[龇牙]@2x.png","k_1g3ju6v":"[钻戒]@2x.png","k_0gl51l6":"[左车头]@2x.png","k_0iflllk":"[左哼哼]@2x.png","k_0g1y3ir":"[左太极]@2x.png","k_026hiq5":"消息列表加载中","k_003tu8k":"爱你","k_003myvp":"傲慢","k_003kddw":"白眼","k_039yfhv":"棒棒糖","k_003nu3p":"抱抱","k_003nijr":"抱拳","k_003mg88":"爆筋","k_002v17e":"鄙视","k_003qhy4":"闭嘴","k_003l5fq":"鞭炮","k_003uacl":"便便","k_003oq1g":"擦汗","k_003qvey":"彩带","k_003jci7":"彩球","k_003pyu1":"菜刀","k_003q97d":"差劲","k_003po5d":"车厢","k_03eadb2":"打哈欠","k_003pnuf":"大兵","k_003kg57":"蛋糕","k_003mxkt":"得意","k_003onu3":"灯泡","k_002uv8s":"凋谢","k_003kqy0":"调皮","k_003tyum":"多云","k_003pv9u":"发呆","k_036o6mu":"发抖t","k_003nogx":"飞机","k_003q7wg":"飞吻","k_003m0jd":"奋斗","k_002ult9":"风车","k_003r8gt":"尴尬","k_003qy4u":"勾引","k_003mnoa":"鼓掌","k_003lmw8":"害羞","k_003mb30":"憨笑","k_03bj41g":"红灯笼","k_03dxw2f":"红双喜","k_003mk57":"坏笑","k_003nmvf":"挥手","k_003r2i7":"回头","k_002s6f3":"饥饿","k_003qd0t":"激动","k_002vgi4":"街舞","k_003nz33":"惊恐","k_002wh4p":"惊讶","k_003ozpu":"咖啡","k_003qvs4":"磕头","k_003l3wb":"可爱","k_003nuwm":"可怜","k_002rw1q":"抠鼻","k_002tujb":"骷髅","k_00030eq":"酷","k_03i8ath":"快哭了","k_000421h":"困","k_003l5i7":"蜡烛","k_003j72g":"篮球","k_003ofwl":"冷汗","k_02mw65v":"礼品袋","k_003ku40":"礼物","k_003ookz":"流汗","k_003on72":"流泪","k_003rjy0":"麻将","k_003q2f8":"猫咪","k_03et393":"么么哒","k_003j7j2":"玫瑰","k_002sr0b":"米饭","k_003nnza":"面条","k_003jef9":"奶瓶","k_002umn0":"难过","k_002rjib":"闹钟","k_0003zcn":"怒","k_003jzwq":"怄火","k_003j4js":"皮球","k_002r5ir":"啤酒","k_002ubu4":"瓢虫","k_003ppo6":"撇嘴","k_003ty3o":"乒乓","k_002vxwe":"汽车","k_00043hb":"强","k_003nmbo":"敲打","k_002tfhq":"青蛙","k_03i7lrn":"糗大了","k_003r03m":"拳头","k_00043h0":"弱","k_000345z":"色","k_003qmp9":"沙发","k_003it8a":"闪电","k_003pxow":"胜利","k_003kw8e":"示爱","k_003n99g":"手枪","k_00035cl":"衰","k_002vl3h":"睡觉","k_002rgqk":"太阳","k_003m9d1":"跳绳","k_002vobp":"跳跳","k_003mkoz":"偷笑","k_00041px":"吐","k_003rjh5":"委屈","k_003j36u":"西瓜","k_002re92":"下雨","k_00041py":"吓","k_003q06o":"献吻","k_002ubjp":"香蕉","k_003o2tr":"象棋","k_03ie6pa":"心碎了","k_003rao5":"信封","k_003l3us":"熊猫","k_000424d":"嘘","k_00033yi":"药","k_002qtyy":"疑问","k_002qe0o":"阴险","k_03gu7us":"右车头","k_03ere8m":"右哼哼","k_003uqk3":"雨伞","k_003tzdv":"月亮","k_0003z00":"晕","k_002vdrd":"再见","k_003ra1w":"炸弹","k_003lcad":"折磨","k_003q7sz":"纸巾","k_002thn9":"咒骂","k_003qx7f":"猪头","k_003l044":"抓狂","k_003qg4h":"转圈","k_003kb97":"龇牙","k_03gu53l":"左车头","k_03erd1f":"左哼哼","k_003nyvl":"爱情","k_003r85z":"爱心","k_003mk8j":"钞票","k_003pwfj":"大哭","k_00042w5":"刀","k_003nmtr":"握手","k_03c529p":"右太极","k_003n4mk":"钻戒","k_03c5488":"左太极","k_1llp7tu":"该用户不存在","k_0tbyqyb":"加载中…","k_0td1p3f":"保存中…","k_1klqdh1":"仅限汉字、英文、数字和下划线","k_03el5lp":"未填写","k_1ui0gai":"搜索指定内容","k_003nvk2":"消息","k_03agld7":"群提示","k_002wkr3":"翻译","k_13g4hxv":"翻译完成","k_1qqgjra":"$option3条未读消息","k_0uubyjr":"以下为未读消息"} \ No newline at end of file +{"k_1yemzyd":"收到一條訊息","k_0ylosxn":"自定義訊息","k_13sajrj":"貼圖訊息","k_13sjeb7":"檔案訊息","k_0yd2ft8":"群提示訊息","k_13s7mxn":"圖片訊息","k_13satlt":"位置訊息","k_00bbtsx":"合並轉發訊息","k_13sqwu4":"語音訊息","k_13sqjjp":"影片","k_1fdhj9g":"該版本不支持此訊息","k_06pujtm":"同意任何用戶添加好友","k_0gyhkp5":"需要驗證","k_121ruco":"拒絕任何人加好友","k_05nspni":"自定義字段","k_03fchyy":"群頭像","k_03i9mfe":"群簡介","k_03agq58":"群名稱","k_039xqny":"群通知","k_003tr0a":"群主","k_03iqsh4":"$s為 ","k_191t5n4":"$opUserNickName修改","k_1pg6aoj":"$opUserNickName退出群組","k_1f6zt3v":"邀請$invitedMemberString加入群組","k_0y7zd07":"將$invitedMemberString踢出群組","k_03c49qt":"去授權","k_1d5mshh":"用戶$joinedMemberString加入了群組","k_002wddw":"禁言","k_0got6f7":"解除禁言","k_0yenqf0":"$userName 被","k_0spotql":"將 $adminMember 設置為管理員","k_0pg5zzj":"系統訊息 $operationType","k_0ohzb9l":"通話時間:$callTime","k_1uaqed6":"[自定義]","k_0z2z7rx":"[語音]","k_0y39ngu":"[貼圖]","k_1c7z88n":"[檔案] $fileName","k_0y1a2my":"[圖片]","k_0z4fib8":"[影片]","k_0y24mcg":"[位置]","k_0pewpd1":"[聊天記錄]","k_13s8d9p":"未知訊息","k_1c3us5n":"當前群組不支持@全體成員","k_11k579v":"發言中有非法語句","k_003qkx2":"日歷","k_003n2pz":"相機","k_03idjo0":"聯絡人","k_003ltgm":"位置","k_02k3k86":"咪高風","k_003pm7l":"相冊","k_15ao57x":"相冊寫入","k_164m3jd":"本地存儲","k_0qba4ns":"想訪問您的$yoursItem","k_03r6qyx":"我們需要您的同意才能獲取信息","k_02noktt":"不允許","k_00043x4":"好","k_003qzac":"昨天","k_003r39d":"前天","k_03fqp9o":"星期天","k_03ibg5h":"星期一","k_03i7hu1":"星期二","k_03iaiks":"星期三","k_03el9pa":"星期四","k_03i7ok1":"星期五","k_03efxyg":"星期六","k_0oozw9x":"$diffMinutes 分鐘前","k_003q7ba":"下午","k_003q7bb":"上午","k_003pu3h":"現在","k_13hzn00":"昨天 $yesterday","k_0n9pyxz":"用戶不存在","k_1bjwemh":"搜尋用戶 ID","k_003kv3v":"搜尋","k_02owlq8":"我的用戶ID: $userID","k_1wu8h4x":"我是: $showName","k_16758qw":"添加好友","k_1shx4d9":"個性簽名: $selfSignature","k_0i553x0":"填寫驗證信息","k_031ocwx":"請填寫備註和分組","k_003ojje":"備註","k_003lsav":"分組","k_167bdvq":"我的好友","k_156b4ut":"好友申請已發送","k_002r305":"發送","k_03gu05e":"聊天室","k_03b4f3p":"會議群","k_03avj1p":"公開群","k_03asq2g":"工作群","k_03b3hbi":"未知群","k_1loix7s":"群類型: $groupType","k_1lqbsib":"該群組不存在","k_03h153m":"搜尋群ID","k_0oxak3r":"群申請已發送","k_002rflt":"刪除","k_1don84v":"無法定位到原訊息","k_003q5fi":"復製","k_003prq0":"轉發","k_002r1h2":"多選","k_003j708":"引用","k_003pqpr":"回收","k_03ezhho":"已復製","k_11ctfsz":"暫未實現","k_1hbjg5g":"[群系統訊息]","k_03tvswb":"[未知訊息]","k_155cj23":"您回收了一條訊息,","k_0gapun3":"重新編輯","k_1uh417q":"$displayName回收了一條訊息","k_1aszp2k":"您確定要重發這條訊息麽?","k_003rzap":"確定","k_003nevv":"取消","k_0003z7x":"您","k_002wfe4":"已讀","k_002wjlg":"未讀","k_0h1ygf8":"發起通話","k_0h169j0":"取消通話","k_0h13jjk":"接受通話","k_0h19hfx":"拒絕通話","k_0obi9lh":"超時未接聽","k_0y9u662":"「$appName」暫不可以開啟此類檔案,你可以使用其他應用開啟並預覽","k_001nmhu":"用其他應用開啟","k_1ht1b80":"正在接收中","k_105682d":"圖片載入失敗","k_0pytyeu":"圖片保存成功","k_0akceel":"圖片保存失敗","k_003rk1s":"保存","k_04a0awq":"[語音訊息]","k_105c3y3":"影片載入失敗","k_176rzr7":"聊天記錄","k_0d5z4m5":"選擇提醒人","k_003ngex":"完成","k_1665ltg":"發起呼叫","k_003n8b0":"拍攝","k_003kthh":"照片","k_003tnp0":"檔案","k_0jhdhtp":"發送失敗,影片不能大於100MB","k_119ucng":"圖片不能為空","k_0w9x8gw":"選擇成功$successPath","k_13dsw4l":"松開取消","k_0am7r68":"手指上滑,取消發送","k_15jl6qw":"說話時間太短!","k_0gx7vl6":"按住說話","k_15dlafd":"逐條轉發","k_15dryxy":"合並轉發","k_1eyhieh":"確定刪除已選訊息","k_17fmlyf":"清除聊天","k_0dhesoz":"取消置頂","k_002sk7x":"置頂","k_003ll77":"草稿","k_03icaxo":"自定義","k_1969986":"[語音通話]:$callingLastMsgShow","k_1960dlr":"[視訊通話]:$callingLastMsgShow","k_1np495n":"$messageString[有人@我]","k_1m797yi":"$messageString[@所有人]","k_1uaov41":"查找聊天內容","k_003kfai":"未知","k_13dq4an":"自動審批","k_0l13cde":"管理員審批","k_11y8c6a":"禁止加群","k_1kvyskd":"無網絡連接,無法修改","k_16payqf":"加群方式","k_0vzvn8r":"修改群名稱","k_038lh6u":"群管理","k_0k5wyiy":"設置管理員","k_0goiuwk":"全員禁言","k_1g889xx":"全員禁言開啟後,只允許群主和管理員發言。","k_0wlrefq":"添加需要禁言的群成員","k_0goox5g":"設置禁言","k_08daijh":"成功取消管理員身份","k_0bxm97s":"管理員 ($adminNum/10)","k_0k5u935":"添加管理員","k_03enyx5":"群成員","k_0jayw3z":"群成員($groupMemberNum人)","k_0h1svv1":"刪除群成員","k_0h1g636":"添加群成員","k_0uj7208":"無網絡連接,無法查看群成員","k_01yfa4o":"$memberCount人","k_0hpukyx":"查看更多群成員","k_0qtsar0":"訊息免打擾","k_0ef2a12":"修改我的群昵稱","k_1aajych":"僅限中文、字母、數字和下劃線,2-20個字","k_137pab5":"我的群昵稱","k_0ivim6d":"暫無群公告","k_03eq6cn":"群公告","k_002vxya":"編輯","k_17fpl3y":"置頂聊天","k_03es1ox":"群類型","k_003mz1i":"同意","k_003lpre":"拒絕","k_003qk66":"頭像","k_003lhvk":"昵稱","k_003ps50":"賬號","k_15lx52z":"個性簽名","k_003qgkp":"性別","k_003m6hr":"生日","k_0003v6a":"男","k_00043x2":"女","k_03bcjkv":"未設置","k_11s0gdz":"修改昵稱","k_0p3j4sd":"僅限中字、字母、數字和下劃線","k_15lyvdt":"修改簽名","k_0vylzjp":"這個人很懶,什麽也沒寫","k_1hs7ese":"等上線再改這個","k_03exjk7":"備註名","k_0s3skfd":"加入黑名單","k_0p3b31s":"修改備註名","k_0003y9x":"無","k_11zgnfs":"個人資料","k_03xd79d":"個性簽名: $signature","k_1tez2xl":"暫無個性簽名","k_118prbn":"全局搜尋","k_1m9dftc":"全部聯絡人","k_0em4gyz":"全部群組","k_002twmj":"群組","k_09kga0d":"更多聊天記錄","k_1ui5lzi":"$count條相關聊天記錄","k_09khmso":"相關聊天記錄","k_1kevf4k":"與$receiver的聊天記錄","k_0vjj2kp":"群組的聊天記錄","k_003n2rp":"選擇","k_03ignw6":"所有人","k_03erpei":"管理員","k_0qi9tno":"群主、管理員","k_1m9exwh":"最近聯絡人","k_119nwqr":"輸入不能為空","k_0pzwbmg":"影片保存成功","k_0aktupv":"影片保存失敗","k_1qbg9xc":"$option8為 ","k_1wq5ubm":"$option7修改","k_0y5pu80":"$option6退出群組","k_0nl7cmd":"邀請$option5加入群組","k_1ju5iqw":"將$option4踢出群組","k_1ovt677":"用戶$option3加入了群組","k_0k05b8b":"$option2 被","k_0wm4xeb":"系統訊息 $option2","k_0nbq9v3":"通話時間:$option2","k_0i1kf53":"[檔案] $option2","k_1gnnby6":"想訪問您的$option2","k_1wh4atg":"$option2 分鐘前","k_07sh7g1":"昨天 $option2","k_1pj8xzh":"我的用戶ID: $option2","k_0py1evo":"個性簽名: $option2","k_1kvj4i2":"$option2回收了一條訊息","k_1v0lbpp":"「$option2」暫不可以開啟此類檔案,你可以使用其他應用開啟並預覽","k_0torwfz":"選擇成功$option2","k_0i1bjah":"$option1回收了一條訊息","k_1qzxh9q":"通話時間:$option3","k_0wrgmom":"[語音通話]:$option1","k_06ix2f0":"[視訊通話]:$option2","k_08o3z5w":"[檔案] $option1","k_0ezbepg":"$option2[有人@我]","k_1ccnht1":"$option2[@所有人]","k_1k3arsw":"管理員 ($option2/10)","k_1d4golg":"群成員($option1人)","k_1bg69nt":"$option1人","k_00gjqxj":"個性簽名: $option1","k_0c29cxr":"$option1條相關聊天記錄","k_1twk5rz":"與$option1的聊天記錄","k_1vn4xq1":"將 $adminMember 取消管理員","k_0e35hsw":"為方便您將所拍攝的照片或影片發送給朋友,以及進行視訊通話,請允許我們訪問攝像頭進行拍攝照片和影片。","k_0dj6yr7":"為方便您發送語音訊息、拍攝影片以及音視訊通話,請允許我們使用咪高風進行錄音。","k_003qnsl":"存儲","k_0s3rtpw":"為方便您查看和選擇相冊裏的圖片影片發送給朋友,以及保存內容到設備,請允許我們訪問您設備上的照片、媒體內容。","k_0tezv85":" 申請獲取$option2","k_002rety":"權限","k_18o68ro":"需要授予","k_1onpf8u":" 相機權限,以正常使用拍攝圖片/影片、視訊通話等功能。","k_17irga5":" 咪高風權限,以正常使用發送語音訊息、拍攝影片、音視訊通話等功能。","k_0572kc4":" 訪問照片權限,以正常使用發送圖片、影片等功能。","k_0slykws":" 訪問相冊寫入權限,以正常使用存儲圖片、影片等功能。","k_119pkcd":" 檔案讀寫權限,以正常使用在聊天功能中的圖片查看、選擇能力和發送檔案的能力。","k_0gqewd3":"以後再說","k_03eq4s1":"去開啟","k_0nt2uyg":"回到最新位置","k_04l16at":"$option1條新訊息","k_13p3w93":"有人@我","k_18w5uk6":"@所有人","k_0jmujgh":"其他檔案正在接收中","k_12s5ept":"訊息詳情","k_0mxa4f4":"$option1人已讀","k_061tue3":"$option2人未讀","k_18qjstb":"轉讓群主","k_0on1aj2":"有$option2條@我訊息","k_09j4izl":"[有人@我] ","k_1oqtjw0":"[@所有人] ","k_1x5a9vb":"我是: $option1","k_14n31e7":"進群請求","k_08nc5j1":"群類型: $option1","k_1josu12":"$option1 條入群請求","k_0n2x5s0":"驗證消息: $option2","k_03c1nx0":"已同意","k_03aw9w8":"已拒絕","k_038ryos":"去處理","k_0gw8pum":"進群申請","k_1gcvfrj":"請填寫備註名","k_002v9zj":"确认","k_10oqrki":"轻触拍照","k_0f8b3ws":"加载失败","k_11cm5lm":"手动聚焦","k_002uzrd":"预览","k_003qkn3":"录像","k_003k6a7":"拍照","k_0bqpqco":"拍照按钮","k_1626ozl":"停止录像","k_003lvmu":"前置","k_003lued":"后置","k_003lwzh":"外置","k_002qzi3":"关闭","k_003pufb":"自动","k_0apm0ze":"拍照时闪光","k_157zog5":"始终闪光","k_0cfyqhy":"$option1 画面预览","k_0phctlz":"闪光模式: $option2","k_02vfqe0":"切换至 $option3 摄像头","k_0f0y9ex":"说话时间太短","k_0ln70tk":"无法打开URL","k_11a3jdv":"轻触拍照,长按摄像","k_1k18miv":"请传入离开群组生命周期函数,提供返回首页或其他页面的导航方法。","k_1fu9ahv":"全员禁言状态","k_0gmwbnd":"全员禁言中","k_0got2zr":"您被禁言","k_0y9jck8":"你必须自定义search bar,并处理点击跳转","k_0yum3tv":"如使用自定义区域,请在profileWidgetBuilder传入对应组件","k_09kalj0":"清空聊天记录","k_14j5iul":"删除并退出","k_125ru1w":"解散该群","k_0jtutmw":"退出后不会接收到此群聊消息","k_0jtzmqa":"解散后不会接收到此群聊消息","k_0r8fi93":"好友添加成功","k_02qw14e":"好友申请已发出","k_0n3md5x":"当前用户在黑名单","k_094phq4":"好友添加失败","k_129scag":"好友删除成功","k_129uzfn":"好友删除失败","k_1666isy":"清除好友","k_1679vrd":"加为好友","k_1ualc52":"看看对方带来的数据是啥","k_0szluvp":"设置对方在线状态","k_0f4rnf8":"该用户已是好友","k_1tdkom4":"您已是群成员","k_1p2lyuz":"对方正在输入中...","k_1g8wfpy":"...共$option1人","k_12rv9vw":"回应详情","k_0havgi0":"[查看详情 >>](${linkMessage.link})","k_0n9p7g8":"群组不存在","k_1tdh5vn":"您不是群成员","k_0h1q57v":"暂无群成员","k_0y5drq1":"[查看详情 >>]($option1)","k_03pjp61":"[表情消息]","k_1jpvzul":"[自定义消息]","k_03u3bh1":"[文件消息]","k_1odsnsw":"[群消息]","k_03sel4t":"[图片消息]","k_03sfw3r":"[位置消息]","k_03xpuwq":"[合并消息]","k_07ycxwo":"[没有元素]","k_03rc9vz":"[文本消息]","k_046uopf":"[视频消息]","k_0ehmsun":"设备存储空间不足,建议清理,以获得更好使用体验","k_003kmos":"图片","k_002s86q":"视频","k_06bk5ei":"视频消息仅限 mp4 格式","k_13opfxf":"Web网页端不支持搜索","k_1i0o0y2":"暂时仅限 Android/iOS 端","k_045dtzl":"$option1的聊天记录","k_0t0131u":"群资料信息","k_18ok8xz":"消息接收方式","k_03ax3ks":"群资料","k_0sqvoqo":"将 $option1 设置为管理员","k_1gbg1v8":"将 $option1 取消管理员","k_17k64g4":"群聊创建成功!","k_05mn217":"暂未安装表情包插件,如需使用表情相关功能,请根据本文档安装:https://cloud.tencent.com/document/product/269/70746","k_14j17nz":"暂无表情包","k_0fvjexh":"正在下载中","k_1cdagzz":"已加入待下载队列,其他文件下载中","k_0g4vojc":"开始下载","k_1g32es3":"[调皮]@2x.png","k_1g8qorz":"[爱你]@2x.png","k_1g4hmx6":"[爱情]@2x.png","k_1g6b558":"[爱心]@2x.png","k_1g3m4su":"[傲慢]@2x.png","k_1g2jym7":"[白眼]@2x.png","k_0cgkxuw":"[棒棒糖]@2x.png","k_1g48br2":"[抱抱]@2x.png","k_1g49ol8":"[抱拳]@2x.png","k_1g0ras3":"[爆筋]@2x.png","k_1ghy881":"[鄙视]@2x.png","k_1g86bmv":"[闭嘴]@2x.png","k_1g1xs1p":"[鞭炮]@2x.png","k_1g8i6ri":"[便便]@2x.png","k_1g2u5kf":"[擦汗]@2x.png","k_1g60uwh":"[彩带]@2x.png","k_1g1o0d0":"[彩球]@2x.png","k_1g6a6yq":"[菜刀]@2x.png","k_1g6vqo2":"[差劲]@2x.png","k_1g0kvjc":"[钞票]@2x.png","k_1g65x7e":"[车厢]@2x.png","k_0e1tjol":"[打哈欠]@2x.png","k_1g65n58":"[大兵]@2x.png","k_1g7se7o":"[大哭]@2x.png","k_1g03868":"[蛋糕]@2x.png","k_1h8nm66":"[刀]@2x.png","k_1g3dlpi":"[得意]@2x.png","k_1g3u434":"[灯泡]@2x.png","k_1giuqs7":"[凋谢]@2x.png","k_1g8r0r9":"[多云]@2x.png","k_1g7k6i1":"[发呆]@2x.png","k_1g44zsp":"[发抖]@2x.png","k_1g5l96i":"[飞机]@2x.png","k_1g7wsqj":"[飞吻]@2x.png","k_1g49luq":"[奋斗]@2x.png","k_1gixbsm":"[风车]@2x.png","k_1g6cqbq":"[尴尬]@2x.png","k_1g6jbw5":"[勾引]@2x.png","k_1g3lwo1":"[鼓掌]@2x.png","k_1g13nkj":"[害羞]@2x.png","k_1g0mt47":"[憨笑]@2x.png","k_0bxujkf":"[红灯笼]@2x.png","k_0hhaeh8":"[红双喜]@2x.png","k_1g0jnts":"[坏笑]@2x.png","k_1g46g9c":"[挥手]@2x.png","k_1g4vi9g":"[回头]@2x.png","k_1gf7hes":"[饥饿]@2x.png","k_1g6mvsm":"[激动]@2x.png","k_1gku5mf":"[街舞]@2x.png","k_1g4hidg":"[惊恐]@2x.png","k_1gjbrtu":"[惊讶]@2x.png","k_1g6sand":"[咖啡]@2x.png","k_1g4s8rj":"[磕头]@2x.png","k_1g1wn34":"[可爱]@2x.png","k_1g3l0wd":"[可怜]@2x.png","k_1ggaon9":"[抠鼻]@2x.png","k_1ggvcb0":"[骷髅]@2x.png","k_1h8yqjt":"[酷]@2x.png","k_0jac97i":"[快哭了]@2x.png","k_1h8oiby":"[困]@2x.png","k_1g0s5hg":"[蜡烛]@2x.png","k_1g1iuer":"[篮球]@2x.png","k_1g2xjfi":"[冷汗]@2x.png","k_0s5oyqw":"[礼品袋]@2x.png","k_1g1qqvf":"[礼物]@2x.png","k_1g2slew":"[流汗]@2x.png","k_1g3z9xx":"[流泪]@2x.png","k_1g6pabn":"[麻将]@2x.png","k_0pkaxul":"[麦克风]@2x.png","k_1g7m0zj":"[猫咪]@2x.png","k_0ibvtpo":"[么么哒]@2x.png","k_1g1hoh1":"[玫瑰]@2x.png","k_1gfzeow":"[米饭]@2x.png","k_1g5l15p":"[面条]@2x.png","k_1g2hfa6":"[奶瓶]@2x.png","k_1gix9pj":"[难过]@2x.png","k_1giqn6g":"[闹钟]@2x.png","k_1h8kd64":"[怒]@2x.png","k_1g0vui9":"[怄火]@2x.png","k_1g1jsj7":"[皮球]@2x.png","k_1ghdluw":"[啤酒]@2x.png","k_1gl6ec7":"[瓢虫]@2x.png","k_1g7gg5p":"[撇嘴]@2x.png","k_1g8psin":"[乒乓]@2x.png","k_1gjzu3p":"[汽车]@2x.png","k_1h8mr0k":"[强]@2x.png","k_1g45y2n":"[敲打]@2x.png","k_1gkaxsl":"[青蛙]@2x.png","k_0jcfnoo":"[糗大了]@2x.png","k_1g4njy1":"[拳头]@2x.png","k_1h8mqr3":"[弱]@2x.png","k_1h926fg":"[色]@2x.png","k_1g6rtbq":"[沙发]@2x.png","k_1giirh6":"[删除]@2x.png","k_1g14ny9":"[闪电]@2x.png","k_1g6bmsr":"[胜利]@2x.png","k_1g1rytx":"[示爱]@2x.png","k_1g52fbz":"[手枪]@2x.png","k_1h90dam":"[衰]@2x.png","k_1gigiae":"[睡觉]@2x.png","k_1gijchz":"[太阳]@2x.png","k_1g1sgji":"[跳绳]@2x.png","k_1gjwuri":"[跳跳]@2x.png","k_1g0juhk":"[偷笑]@2x.png","k_1h8nzla":"[吐]@2x.png","k_1g6cv0i":"[委屈]@2x.png","k_1g46l5g":"[握手]@2x.png","k_1g2pgkd":"[西瓜]@2x.png","k_1ging9p":"[下雨]@2x.png","k_1h8nzil":"[吓]@2x.png","k_1g7q7wr":"[献吻]@2x.png","k_1gl6uum":"[香蕉]@2x.png","k_1g23fys":"[象棋]@2x.png","k_0j75rdh":"[心碎了]@2x.png","k_1g6ajj2":"[信封]@2x.png","k_1g21prz":"[熊猫]@2x.png","k_1h8octi":"[嘘]@2x.png","k_1h91zox":"[药]@2x.png","k_1ghttfl":"[疑问]@2x.png","k_1ghk7sz":"[阴险]@2x.png","k_0gl37zz":"[右车头]@2x.png","k_0ifkj1p":"[右哼哼]@2x.png","k_0g1yh2e":"[右太极]@2x.png","k_1g9dkfc":"[雨伞]@2x.png","k_1g8jl88":"[月亮]@2x.png","k_1h8lhqj":"[晕]@2x.png","k_1gi9x2q":"[再见]@2x.png","k_1g6dwwv":"[炸弹]@2x.png","k_1fzmkfi":"[折磨]@2x.png","k_1g6jbiw":"[纸巾]@2x.png","k_1ggjnwu":"[咒骂]@2x.png","k_1g4qlq8":"[猪头]@2x.png","k_1g1lqzz":"[抓狂]@2x.png","k_1g80j3u":"[转圈]@2x.png","k_1g0z55s":"[龇牙]@2x.png","k_1g3ju6v":"[钻戒]@2x.png","k_0gl51l6":"[左车头]@2x.png","k_0iflllk":"[左哼哼]@2x.png","k_0g1y3ir":"[左太极]@2x.png","k_026hiq5":"消息列表加载中","k_003tu8k":"爱你","k_003myvp":"傲慢","k_003kddw":"白眼","k_039yfhv":"棒棒糖","k_003nu3p":"抱抱","k_003nijr":"抱拳","k_003mg88":"爆筋","k_002v17e":"鄙视","k_003qhy4":"闭嘴","k_003l5fq":"鞭炮","k_003uacl":"便便","k_003oq1g":"擦汗","k_003qvey":"彩带","k_003jci7":"彩球","k_003pyu1":"菜刀","k_003q97d":"差劲","k_003po5d":"车厢","k_03eadb2":"打哈欠","k_003pnuf":"大兵","k_003kg57":"蛋糕","k_003mxkt":"得意","k_003onu3":"灯泡","k_002uv8s":"凋谢","k_003kqy0":"调皮","k_003tyum":"多云","k_003pv9u":"发呆","k_036o6mu":"发抖t","k_003nogx":"飞机","k_003q7wg":"飞吻","k_003m0jd":"奋斗","k_002ult9":"风车","k_003r8gt":"尴尬","k_003qy4u":"勾引","k_003mnoa":"鼓掌","k_003lmw8":"害羞","k_003mb30":"憨笑","k_03bj41g":"红灯笼","k_03dxw2f":"红双喜","k_003mk57":"坏笑","k_003nmvf":"挥手","k_003r2i7":"回头","k_002s6f3":"饥饿","k_003qd0t":"激动","k_002vgi4":"街舞","k_003nz33":"惊恐","k_002wh4p":"惊讶","k_003ozpu":"咖啡","k_003qvs4":"磕头","k_003l3wb":"可爱","k_003nuwm":"可怜","k_002rw1q":"抠鼻","k_002tujb":"骷髅","k_00030eq":"酷","k_03i8ath":"快哭了","k_000421h":"困","k_003l5i7":"蜡烛","k_003j72g":"篮球","k_003ofwl":"冷汗","k_02mw65v":"礼品袋","k_003ku40":"礼物","k_003ookz":"流汗","k_003on72":"流泪","k_003rjy0":"麻将","k_003q2f8":"猫咪","k_03et393":"么么哒","k_003j7j2":"玫瑰","k_002sr0b":"米饭","k_003nnza":"面条","k_003jef9":"奶瓶","k_002umn0":"难过","k_002rjib":"闹钟","k_0003zcn":"怒","k_003jzwq":"怄火","k_003j4js":"皮球","k_002r5ir":"啤酒","k_002ubu4":"瓢虫","k_003ppo6":"撇嘴","k_003ty3o":"乒乓","k_002vxwe":"汽车","k_00043hb":"强","k_003nmbo":"敲打","k_002tfhq":"青蛙","k_03i7lrn":"糗大了","k_003r03m":"拳头","k_00043h0":"弱","k_000345z":"色","k_003qmp9":"沙发","k_003it8a":"闪电","k_003pxow":"胜利","k_003kw8e":"示爱","k_003n99g":"手枪","k_00035cl":"衰","k_002vl3h":"睡觉","k_002rgqk":"太阳","k_003m9d1":"跳绳","k_002vobp":"跳跳","k_003mkoz":"偷笑","k_00041px":"吐","k_003rjh5":"委屈","k_003j36u":"西瓜","k_002re92":"下雨","k_00041py":"吓","k_003q06o":"献吻","k_002ubjp":"香蕉","k_003o2tr":"象棋","k_03ie6pa":"心碎了","k_003rao5":"信封","k_003l3us":"熊猫","k_000424d":"嘘","k_00033yi":"药","k_002qtyy":"疑问","k_002qe0o":"阴险","k_03gu7us":"右车头","k_03ere8m":"右哼哼","k_003uqk3":"雨伞","k_003tzdv":"月亮","k_0003z00":"晕","k_002vdrd":"再见","k_003ra1w":"炸弹","k_003lcad":"折磨","k_003q7sz":"纸巾","k_002thn9":"咒骂","k_003qx7f":"猪头","k_003l044":"抓狂","k_003qg4h":"转圈","k_003kb97":"龇牙","k_03gu53l":"左车头","k_03erd1f":"左哼哼","k_003nyvl":"爱情","k_003r85z":"爱心","k_003mk8j":"钞票","k_003pwfj":"大哭","k_00042w5":"刀","k_003nmtr":"握手","k_03c529p":"右太极","k_003n4mk":"钻戒","k_03c5488":"左太极","k_1llp7tu":"该用户不存在","k_0tbyqyb":"加载中…","k_0td1p3f":"保存中…","k_1klqdh1":"仅限汉字、英文、数字和下划线","k_03el5lp":"未填写","k_1ui0gai":"搜索指定内容","k_003nvk2":"消息","k_03agld7":"群提示","k_0elt0kw":"添加群聊","k_0s3sgel":"移出黑名单","k_1qqgjra":"$option3条未读消息","k_0uubyjr":"以下为未读消息","k_16as7eq":"表情回应","k_003s12u":"回复","k_003s38r":"更多","k_002wkr3":"翻译","k_13g4hxv":"翻译完成","k_003molk":"表情","k_165bbw6":"消息历史","k_13sqc0z":"清除消息","k_0glns86":"删除会话","k_13s99rx":"清空消息","k_11vsa3j":"退出群组","k_11vvszp":"解散群组","k_15i9w72":"群管理员","k_0p3espj":"设置备注名","k_118sw9v":"立即搜索","k_0h20hg5":"视频通话","k_0h22snw":"语音通话","k_003lz6t":"对方","k_1xf4yre":"发送给$option1","k_003por5":"截图","k_1rw7s82":" 访问相册中视频权限,以正常使用发送视频等功能。","k_003rcwm":"打开","k_1698c42":"在访达中打开","k_066fxsz":"查看文件夹","k_0k432y2":"无法发送,包含文件夹","k_002wb4y":"会话"} \ No newline at end of file diff --git a/lib/tencent_cloud_chat_uikit.dart b/lib/tencent_cloud_chat_uikit.dart index 4c8ec65..90cc3dd 100644 --- a/lib/tencent_cloud_chat_uikit.dart +++ b/lib/tencent_cloud_chat_uikit.dart @@ -32,12 +32,12 @@ export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/tim_uikit_searc export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_controller.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list.dart'; -export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart'; export 'package:tencent_im_base/tencent_im_base.dart'; export 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/models/link_preview_content.dart'; -export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card.dart'; +export 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart'; +export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart'; export 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitConversation/tim_ui_kit_conversation_total_unread.dart'; // Enum @@ -52,6 +52,7 @@ export 'package:permission_handler/permission_handler.dart'; // Utils export 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; +export 'package:tencent_cloud_uikit_core/tencent_cloud_uikit_core.dart'; class TIMUIKitCore { static CoreServicesImpl getInstance() { diff --git a/lib/ui/controller/tim_uikit_chat_controller.dart b/lib/ui/controller/tim_uikit_chat_controller.dart index 2152058..a2fadb7 100644 --- a/lib/ui/controller/tim_uikit_chat_controller.dart +++ b/lib/ui/controller/tim_uikit_chat_controller.dart @@ -17,17 +17,16 @@ class TIMUIKitChatController { } } - Future loadHistoryMessageList({ - HistoryMsgGetTypeEnum getType = - HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG, - String? userID, - String? groupID, - int lastMsgSeq = -1, - required int count, - String? lastMsgID, - LoadDirection direction = LoadDirection.previous - }) async { - return await model?.loadData( + Future loadHistoryMessageList( + {HistoryMsgGetTypeEnum getType = + HistoryMsgGetTypeEnum.V2TIM_GET_CLOUD_OLDER_MSG, + String? userID, + String? groupID, + int lastMsgSeq = -1, + required int count, + String? lastMsgID, + LoadDirection direction = LoadDirection.previous}) async { + return await model?.loadChatRecord( count: count, getType: getType, lastMsgID: lastMsgID, @@ -70,7 +69,6 @@ class TIMUIKitChatController { /// Please provide `convID`, if you use `TIMUIKitChatController` without specifying to a `TIMUIKitChat`. Future updateMessage( { - /// The ID of the target conversation String? convID, @@ -88,32 +86,47 @@ class TIMUIKitChatController { return; } - /// Send message; - /// 发送消息 - /// Please provide `convType` and `convID`, if you use `TIMUIKitChatController` without specifying to a `TIMUIKitChat`. + /// Sends a message to the specified conversation, or to the current conversation specified on `TIMUIKitChat`. + /// 发送消息到指定的对话,或者发送到 `TIMUIKitChat` 中指定的当前对话。 + /// You must provide `convType` and either `userID` or `groupID`, only if you use `TIMUIKitChat` without specifying a `TIMUIKitChatController`, you must provide these parameters. + /// 您需要提供 `convType` 和 `userID` 或 `groupID`, 只有在如果您使用 `TIMUIKitChat` 而没有指定 `TIMUIKitChatController`,则必须提供这些参数。 Future?>? sendMessage({ required V2TimMessage? messageInfo, - /// The type of the target conversation + /// The type of the target conversation: either ConvType.group or ConvType.c2c. Required if using `TIMUIKitChat` without specifying a `TIMUIKitChatController`. + /// 目标对话的类型:ConvType.group 或 ConvType.c2c。只有在如果您使用 `TIMUIKitChat` 而没有指定 `TIMUIKitChatController`,则必须提供此参数。 ConvType? convType, - /// The ID of the target conversation - String? convID, + /// The user ID of the target one-to-one conversation. Required if convType is ConvType.c2c. + /// 目标一对一对话的用户 ID。如果 convType 是 ConvType.c2c,则必填。 + String? userID, - /// The method for updating the input field when message sending failed + /// The target group ID. Required if convType is ConvType.group. + /// 目标群组的 ID。如果 convType 是 ConvType.group,则必填。 + String? groupID, + + /// A callback function to update the input field when message sending fails. + /// 当消息发送失败时,用于更新输入框的回调函数。 ValueChanged? setInputField, - /// Offline push info + /// Offline push information. + /// 离线推送信息。 OfflinePushInfo? offlinePushInfo, }) { - if (convID != null && convType != null) { + if (convType != null) { + /// Sends a message to the specified conversation. 发送消息到指定的对话。 + assert((groupID == null) != (userID == null)); + assert(groupID != null || convType != ConvType.group); + assert(userID != null || convType != ConvType.c2c); + return globalChatModel.sendMessageFromController( messageInfo: messageInfo, convType: convType, - convID: convID, + convID: (convType == ConvType.group ? groupID : userID) ?? "", setInputField: setInputField, offlinePushInfo: offlinePushInfo); } else if (model != null) { + /// Sends a message to the current conversation specified on `TIMUIKitChat`. 发送到 `TIMUIKitChat` 中指定的当前对话。 return model!.sendMessageFromController( messageInfo: messageInfo, offlinePushInfo: offlinePushInfo); } diff --git a/lib/ui/controller/tim_uikit_conversation_controller.dart b/lib/ui/controller/tim_uikit_conversation_controller.dart index 9979cb2..37e7b0c 100644 --- a/lib/ui/controller/tim_uikit_conversation_controller.dart +++ b/lib/ui/controller/tim_uikit_conversation_controller.dart @@ -9,6 +9,11 @@ class TIMUIKitConversationController { return model.selectedConversation; } + /// Set the selected conversation currently + set selectedConversation(V2TimConversation? conversation) { + model.selectedConversation = conversation; + } + /// Get the conversation list List get conversationList { return model.conversationList; diff --git a/lib/ui/controller/tim_uikit_profile_controller.dart b/lib/ui/controller/tim_uikit_profile_controller.dart index 9fbf53c..f2fe078 100644 --- a/lib/ui/controller/tim_uikit_profile_controller.dart +++ b/lib/ui/controller/tim_uikit_profile_controller.dart @@ -47,15 +47,23 @@ class TIMUIKitProfileController { } /// Show the text input bottom sheet - showTextInputBottomSheet( - BuildContext context, - String title, - String tips, - void Function(String) onSubmitted, - TUITheme theme - ) { + showTextInputBottomSheet({ + required BuildContext context, + required String title, + required String tips, + required Function(String text) onSubmitted, + required TUITheme theme, + Offset? initOffset, + String? initText, + }) { TextInputBottomSheet.showTextInputBottomSheet( - context, title, tips, onSubmitted, theme); + context: context, + title: title, + tips: tips, + onSubmitted: onSubmitted, + theme: theme, + initOffset: initOffset, + initText: initText); } /// Load the profile data diff --git a/lib/ui/utils/common_utils.dart b/lib/ui/utils/common_utils.dart index 5487769..1da0c53 100644 --- a/lib/ui/utils/common_utils.dart +++ b/lib/ui/utils/common_utils.dart @@ -6,4 +6,153 @@ class TencentUtils{ static String? checkString(String? text){ return (text != null && text.isEmpty) ? null : text; } + + static String? checkStringWithoutSpace(String? text){ + if (text == null || text.trim().isEmpty || text.contains(' ')) { + return null; + } + return text; + } + + static String getFileType(String fileType) { + switch (fileType) { + case "3gp": + return "video/3gpp"; + case "torrent": + return "application/x-bittorrent"; + case "kml": + return "application/vnd.google-earth.kml+xml"; + case "gpx": + return "application/gpx+xml"; + case "asf": + return "video/x-ms-asf"; + case "avi": + return "video/x-msvideo"; + case "bin": + case "class": + case "exe": + return "application/octet-stream"; + case "bmp": + return "image/bmp"; + case "c": + return "text/plain"; + case "conf": + return "text/plain"; + case "cpp": + return "text/plain"; + case "doc": + return "application/msword"; + case "docx": + return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + case "xls": + case "csv": + return "application/vnd.ms-excel"; + case "xlsx": + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + case "gif": + return "image/gif"; + case "gtar": + return "application/x-gtar"; + case "gz": + return "application/x-gzip"; + case "h": + return "text/plain"; + case "htm": + return "text/html"; + case "html": + return "text/html"; + case "jar": + return "application/java-archive"; + case "java": + return "text/plain"; + case "jpeg": + return "image/jpeg"; + case "jpg": + return "image/jpeg"; + case "js": + return "application/x-javascript"; + case "log": + return "text/plain"; + case "m3u": + return "audio/x-mpegurl"; + case "m4a": + return "audio/mp4a-latm"; + case "m4b": + return "audio/mp4a-latm"; + case "m4p": + return "audio/mp4a-latm"; + case "m4u": + return "video/vnd.mpegurl"; + case "m4v": + return "video/x-m4v"; + case "mov": + return "video/quicktime"; + case "mp2": + return "audio/x-mpeg"; + case "mp3": + return "audio/x-mpeg"; + case "mp4": + return "video/mp4"; + case "mpc": + return "application/vnd.mpohun.certificate"; + case "mpe": + return "video/mpeg"; + case "mpeg": + return "video/mpeg"; + case "mpg": + return "video/mpeg"; + case "mpg4": + return "video/mp4"; + case "mpga": + return "audio/mpeg"; + case "msg": + return "application/vnd.ms-outlook"; + case "ogg": + return "audio/ogg"; + case "pdf": + return "application/pdf"; + case "png": + return "image/png"; + case "pps": + return "application/vnd.ms-powerpoint"; + case "ppt": + return "application/vnd.ms-powerpoint"; + case "pptx": + return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + case "prop": + return "text/plain"; + case "rc": + return "text/plain"; + case "rmvb": + return "audio/x-pn-realaudio"; + case "rtf": + return "application/rtf"; + case "sh": + return "text/plain"; + case "tar": + return "application/x-tar"; + case "tgz": + return "application/x-compressed"; + case "txt": + return "text/plain"; + case "wav": + return "audio/x-wav"; + case "wma": + return "audio/x-ms-wma"; + case "wmv": + return "audio/x-ms-wmv"; + case "wps": + return "application/vnd.ms-works"; + case "xml": + return "text/plain"; + case "z": + return "application/x-compress"; + case "zip": + return "application/x-zip-compressed"; + default: + return "*/*"; + } + } + + } \ No newline at end of file diff --git a/lib/ui/utils/message.dart b/lib/ui/utils/message.dart index 0a28527..32575ef 100644 --- a/lib/ui/utils/message.dart +++ b/lib/ui/utils/message.dart @@ -1,13 +1,12 @@ // ignore_for_file: unrelated_type_equality_checks, avoid_print import 'dart:convert'; - -import 'package:collection/collection.dart'; import 'package:flutter/cupertino.dart'; -import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/time.dart'; +import 'package:collection/collection.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; class MessageUtils { // 判断CallingData的方式和Trtc的方法一致 @@ -101,9 +100,12 @@ class MessageUtils { } static String? _getOpUserNick(V2TimGroupMemberInfo? opUser) { - return TencentUtils.checkString(opUser?.friendRemark) ?? - TencentUtils.checkString(opUser?.nickName) ?? - TencentUtils.checkString(opUser?.userID) ?? ""; + if(opUser == null){ + return ""; + } + return TencentUtils.checkString(opUser.friendRemark) ?? + TencentUtils.checkString(opUser.nickName) ?? + TencentUtils.checkString(opUser.userID); } static String? _getMemberNickName(V2TimGroupMemberInfo e) { @@ -155,21 +157,21 @@ class MessageUtils { break; case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_INVITE: final option5 = - memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); + memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); final inviteUser = _getOpUserNick(operationMember); displayMessage = '$inviteUser' + TIM_t_para("邀请{{option5}}加入群组", "邀请$option5加入群组")(option5: option5); break; case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_KICKED: final option4 = - memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); + memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); final kickUser = _getOpUserNick(operationMember); displayMessage = '$kickUser' + TIM_t_para("将{{option4}}踢出群组", "将$option4踢出群组")(option4: option4); break; case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_JOIN: final option3 = - memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); + memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); displayMessage = TIM_t_para("用户{{option3}}加入了群聊", "用户$option3加入了群聊")( option3: option3); break; @@ -186,7 +188,7 @@ class MessageUtils { break; case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_SET_ADMIN: final adminMember = - memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); + memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); final opMember = _getOpUserNick(operationMember); final option1 = adminMember; displayMessage = '$opMember' + @@ -195,7 +197,7 @@ class MessageUtils { break; case GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_CANCEL_ADMIN: final adminMember = - memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); + memberList!.map((e) => _getMemberNickName(e!).toString()).join("、"); final opMember = _getOpUserNick(operationMember); final option1 = adminMember; displayMessage = '$opMember' + @@ -276,46 +278,14 @@ class MessageUtils { } } - static Future getAbstractMessage(V2TimMessage message, - List groupMemberList) async { - final msgType = message.elemType; - switch (msgType) { - case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM: - return handleCustomMessageString(message); - case MessageElemType.V2TIM_ELEM_TYPE_SOUND: - return TIM_t("[语音]"); - case MessageElemType.V2TIM_ELEM_TYPE_TEXT: - return message.textElem!.text as String; - case MessageElemType.V2TIM_ELEM_TYPE_FACE: - return TIM_t("[表情]"); - case MessageElemType.V2TIM_ELEM_TYPE_FILE: - final String? option2 = message.fileElem!.fileName ?? ""; - return TIM_t_para("[文件] {{option2}}", "[文件] $option2")( - option2: option2); - case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS: - return await MessageUtils.groupTipsMessageAbstract( - message.groupTipsElem!, groupMemberList); - case MessageElemType.V2TIM_ELEM_TYPE_IMAGE: - return TIM_t("[图片]"); - case MessageElemType.V2TIM_ELEM_TYPE_VIDEO: - return TIM_t("[视频]"); - case MessageElemType.V2TIM_ELEM_TYPE_LOCATION: - return TIM_t("[位置]"); - case MessageElemType.V2TIM_ELEM_TYPE_MERGER: - return TIM_t("[聊天记录]"); - default: - return TIM_t("未知消息"); - } - } - static V2TimImage? getImageFromImgList( List? list, List order) { V2TimImage? img; try { for (String type in order) { img = list?.firstWhere( - (e) => - e?.type == HistoryMessageDartConstant.V2_TIM_IMAGE_TYPES[type], + (e) => + e?.type == HistoryMessageDartConstant.V2_TIM_IMAGE_TYPES[type], orElse: () => null); } } catch (e) { @@ -332,10 +302,10 @@ class MessageUtils { final displayName = friendRemark.isNotEmpty ? friendRemark : nameCard.isNotEmpty - ? nameCard - : nickName.isNotEmpty - ? nickName - : sender; + ? nameCard + : nickName.isNotEmpty + ? nickName + : sender; return displayName.toString(); } diff --git a/lib/ui/utils/permission.dart b/lib/ui/utils/permission.dart index 74b1e29..675d05b 100644 --- a/lib/ui/utils/permission.dart +++ b/lib/ui/utils/permission.dart @@ -1,6 +1,7 @@ // ignore_for_file: unused_import import 'dart:io'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -11,6 +12,7 @@ import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; + class PermissionRequestInfo extends StatefulWidget { final Function removeOverLay; final int permissionType; @@ -32,14 +34,14 @@ class _PermissionRequestInfo extends TIMUIKitState @override void initState() { super.initState(); - WidgetsBinding.instance?.addObserver(this); + WidgetsBinding.instance.addObserver(this); } @override void dispose() { widget.removeOverLay(); super.dispose(); - WidgetsBinding.instance?.removeObserver(this); + WidgetsBinding.instance.removeObserver(this); } @override @@ -65,11 +67,21 @@ class _PermissionRequestInfo extends TIMUIKitState "icon": "images/chat_permission_icon_mic.png", "text": TIM_t("为方便您发送语音消息、拍摄视频以及音视频通话,请允许我们使用麦克风进行录音。") }, + 9: { + "name": TIM_t("相册"), + "icon": "images/chat_permission_icon_file.png", + "text": TIM_t("为方便您查看和选择相册里的图片视频发送给朋友,以及保存内容到设备,请允许我们访问您设备上的照片、媒体内容。") + }, 15: { "name": TIM_t("存储"), "icon": "images/chat_permission_icon_file.png", "text": TIM_t("为方便您查看和选择相册里的图片视频发送给朋友,以及保存内容到设备,请允许我们访问您设备上的照片、媒体内容。") }, + 32: { + "name": TIM_t("相册"), + "icon": "images/chat_permission_icon_file.png", + "text": TIM_t("为方便您查看和选择相册里的图片视频发送给朋友,以及保存内容到设备,请允许我们访问您设备上的照片、媒体内容。") + }, }[widget.permissionType]; final option2 = permission?["name"] ?? ""; return Stack( @@ -128,6 +140,9 @@ class _PermissionRequestInfo extends TIMUIKitState } class Permissions { + + static OverlayEntry? _entry; + static List _names(BuildContext context) { return [ TIM_t("日历"), @@ -161,6 +176,10 @@ class Permissions { 'bluetoothScan', 'bluetoothAdvertise', 'bluetoothConnect', + 'nearbyWifiDevices', + TIM_t("视频"), + 'audio', + 'scheduleExactAlarm' ]; } @@ -199,6 +218,10 @@ class Permissions { 'bluetoothScan', 'bluetoothAdvertise', 'bluetoothConnect', + 'nearbyWifiDevices', + TIM_t(" 访问相册中视频权限,以正常使用发送视频等功能。"), + 'audio', + 'scheduleExactAlarm' ]; return _prefix + appName + _postfixList[value]; } @@ -220,7 +243,10 @@ class Permissions { isShowPermissionPage, ); if (shouldRequestPermission != null && shouldRequestPermission) { - return await Permission.byValue(value).request().isGranted; + final isGranted = await Permission.byValue(value).request().isGranted; + _entry?.remove(); + _entry = null; + return isGranted; } return shouldRequestPermission ?? false; } @@ -241,11 +267,13 @@ class Permissions { static showPermissionRequestInfoDialog(BuildContext context, value) async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); String appName = packageInfo.appName; - OverlayEntry? _entry; final entry = OverlayEntry(builder: (context) { return PermissionRequestInfo( appName: appName, - removeOverLay: () => _entry?.remove(), + removeOverLay: () { + _entry?.remove(); + _entry = null; + }, permissionType: value, ); }); @@ -269,6 +297,7 @@ class Permissions { String appName = packageInfo.appName; final option2 = _names(context)[value]; final permissionText = _permissionText(context, appName, value); + void closeDialog() { Navigator.of(context).pop(false); } diff --git a/lib/ui/utils/platform.dart b/lib/ui/utils/platform.dart index 3aa485e..4272f2d 100644 --- a/lib/ui/utils/platform.dart +++ b/lib/ui/utils/platform.dart @@ -5,13 +5,23 @@ class PlatformUtils { PlatformUtils._internal(); static late bool _isAndroid; static late bool _isIos; + static late bool _isMobile; static late bool _isWeb; + static late bool _isWindows; + static late bool _isMacOS; + static late bool _isLinux; + static late bool _isDesktop; static bool _isInstantiation = false; factory PlatformUtils() { if (!_isInstantiation) { _isAndroid = !kIsWeb && Platform.isAndroid; _isIos = !kIsWeb && Platform.isIOS; + _isMobile = _isAndroid || _isIos; + _isWindows = !kIsWeb && Platform.isWindows; + _isMacOS = !kIsWeb && Platform.isMacOS; + _isLinux = !kIsWeb && Platform.isLinux; + _isDesktop = _isMacOS || _isWindows || _isLinux; _isWeb = kIsWeb; _isInstantiation = true; } @@ -32,4 +42,20 @@ class PlatformUtils { get isIOS { return _isIos; } + + get isWindows { + return _isWindows; + } + + get isMacOS { + return _isMacOS; + } + + get isMobile { + return _isMobile; + } + + bool get isDesktop => _isDesktop; + + bool get isLinux => _isLinux; } diff --git a/lib/ui/utils/screen_shot.dart b/lib/ui/utils/screen_shot.dart new file mode 100644 index 0000000..00e7894 --- /dev/null +++ b/lib/ui/utils/screen_shot.dart @@ -0,0 +1,104 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:path/path.dart' as p; +import 'package:path_provider/path_provider.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:uuid/uuid.dart'; + +class ScreenshotHelper { + static Future captureScreen() async { + await requestScreenRecordingPermission(); + String directory; + + if(PlatformUtils().isWindows){ + final String documentsDirectoryPath = + "${Platform.environment['USERPROFILE']}"; + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + String pkgName = packageInfo.packageName; + directory = p.join(documentsDirectoryPath, "Documents", ".TencentCloudChat", + pkgName, "screenshots"); + }else{ + final dic = await getApplicationSupportDirectory(); + directory = dic.path; + } + + const uuid = Uuid(); + final fileName = 'screenshot_${uuid.v4()}.png'; + final filePath = '$directory/$fileName'; + if (Platform.isMacOS) { + // 在macOS平台上使用screencapture工具 + final result = await Process.run( + 'screencapture', + ['-i', '-s', '-o', filePath], + ); + if (result.exitCode == 0) { + return filePath; + } else { + return null; + } + } else if (Platform.isWindows) { + // 在Windows平台上使用snippingtool工具 + final result = await Process.run( + 'snippingtool', + ['/clip', filePath], + ); + if (result.exitCode == 0) { + return filePath; + } else { + return null; + } + } else { + // 不支持的平台 + return null; + } + } + + static Future requestScreenRecordingPermission() async { + if (Platform.isMacOS) { + final result = await Process.run( + 'sh', ['-c', 'echo ${Platform.environment['USER']}']); + final username = result.stdout.toString().trim(); + const script = + 'tell application "System Events" to return exists (processes where name is "ControlCenter")'; + final process = await Process.run('osascript', ['-e', script]); + final isControlCenterRunning = process.stdout.toString().trim() == 'true'; + + if (!isControlCenterRunning) { + await Process.run('open', ['-a', 'ControlCenter']); + await Future.delayed(const Duration(seconds: 1)); + } + + final script2 = 'tell application "ControlCenter" to activate\n' + 'tell application "System Events"\n' + ' tell process "ControlCenter"\n' + ' click menu item "Screen Recording" of menu "File" of menu bar 1\n' + ' delay 0.5\n' + ' keystroke "$username" & return\n' + ' end tell\n' + 'end tell\n'; + await Process.run('osascript', ['-e', script2]); + + await Future.delayed(const Duration(seconds: 1)); + final isScreenRecordingEnabled = await SystemChannels.platform + .invokeMethod('isScreenRecordingEnabled'); + return isScreenRecordingEnabled ?? false; + } else { + return true; + } + } + + static Future getImageSize(String imagePath) async { + final bytes = await File(imagePath).readAsBytes(); + final completer = Completer(); + final imageStream = + Image.memory(bytes).image.resolve(ImageConfiguration.empty); + imageStream.addListener(ImageStreamListener((imageInfo, _) { + completer.complete(Size( + imageInfo.image.width.toDouble(), imageInfo.image.height.toDouble())); + })); + return completer.future; + } +} diff --git a/lib/ui/utils/screen_utils.dart b/lib/ui/utils/screen_utils.dart index 922a9e7..73b839c 100644 --- a/lib/ui/utils/screen_utils.dart +++ b/lib/ui/utils/screen_utils.dart @@ -2,20 +2,40 @@ import 'package:flutter/cupertino.dart'; -enum ScreenType { Desktop, Tablet, Handset, Watch } +enum DeviceType { Desktop, Mobile } class FormFactor { static double desktop = 900; - static double tablet = 600; static double handset = 300; } -class ScreenUtils { - static ScreenType getFormFactor(BuildContext context) { - double deviceWidth = MediaQuery.of(context).size.shortestSide; - if (deviceWidth > FormFactor.desktop) return ScreenType.Desktop; - if (deviceWidth > FormFactor.tablet) return ScreenType.Tablet; - if (deviceWidth > FormFactor.handset) return ScreenType.Handset; - return ScreenType.Watch; +class TUIKitScreenUtils { + static DeviceType? deviceType; + + static DeviceType getFormFactor([BuildContext? context]) { + if (deviceType != null) return deviceType!; + + if(context != null){ + double deviceWidth = MediaQuery.of(context).size.width; + double deviceHeight = MediaQuery.of(context).size.height; + + if (deviceWidth > FormFactor.desktop || deviceWidth > deviceHeight * 1.1) { + deviceType = DeviceType.Desktop; + } else if (deviceWidth > FormFactor.handset) { + deviceType = DeviceType.Mobile; + } + return deviceType ?? DeviceType.Mobile; + }else{ + return DeviceType.Mobile; + } + } + + static Widget getDeviceWidget({ + required Widget defaultWidget, + Widget? desktopWidget, + Widget? mobileWidget, + }) { + if (deviceType == DeviceType.Desktop) return desktopWidget ?? defaultWidget; + return mobileWidget ?? defaultWidget; } } diff --git a/lib/ui/utils/sound_record.dart b/lib/ui/utils/sound_record.dart index c04402e..78ec249 100644 --- a/lib/ui/utils/sound_record.dart +++ b/lib/ui/utils/sound_record.dart @@ -1,5 +1,5 @@ import 'dart:async'; - +import 'package:audioplayers/audioplayers.dart'; import 'package:flutter_plugin_record_plus/const/play_state.dart'; import 'package:flutter_plugin_record_plus/const/response.dart'; import 'package:flutter_plugin_record_plus/index.dart'; @@ -14,33 +14,37 @@ class SoundPlayer { static final FlutterPluginRecord _recorder = FlutterPluginRecord(); static SoundInterruptListener? _soundInterruptListener; static bool isInited = false; + static final AudioPlayer _audioPlayer = AudioPlayer(); static initSoundPlayer() { if (!isInited) { _recorder.init(); + AudioPlayer.global.setGlobalAudioContext(const AudioContext()); isInited = true; } } - static play({required String url}) { - _recorder.stopPlay(); + static Future play({required String url}) async { + _audioPlayer.stop(); if (_soundInterruptListener != null) { _soundInterruptListener!(); } - _recorder.playByPath(url, 'url'); + await _audioPlayer.play(UrlSource(url)); } static stop() { - _recorder.stopPlay(); + _audioPlayer.stop(); } static dispose() { + _audioPlayer.dispose(); _recorder.dispose(); } - static StreamSubscription playStateListener( - {required PlayStateListener listener}) => - _recorder.responsePlayStateController.listen(listener); + static StreamSubscription playStateListener( + {required void Function(PlayerState)? listener}) => + _audioPlayer.onPlayerStateChanged.listen(listener); + static setSoundInterruptListener(SoundInterruptListener listener) { _soundInterruptListener = listener; diff --git a/lib/ui/utils/time_ago.dart b/lib/ui/utils/time_ago.dart index dbb2ac7..95cdbcc 100644 --- a/lib/ui/utils/time_ago.dart +++ b/lib/ui/utils/time_ago.dart @@ -11,18 +11,6 @@ class TimeAgo { ]; } - List daysMap() { - return [ - TIM_t("星期天"), - TIM_t("星期一"), - TIM_t("星期二"), - TIM_t("星期三"), - TIM_t("星期四"), - TIM_t("星期五"), - TIM_t("星期六") - ]; - } - List weekdayMap() { return [ '', @@ -36,7 +24,7 @@ class TimeAgo { ]; } - String getYearMounthDate(DateTime dateTime) { + String getYearMonthDate(DateTime dateTime) { String month = dateTime.month.toString(); String date = dateTime.day.toString(); return dateTime.year.toString() + @@ -48,7 +36,7 @@ class TimeAgo { date; } - String getMounthDate(DateTime dateTime) { + String getMonthDate(DateTime dateTime) { String month = dateTime.month.toString(); String date = dateTime.day.toString(); return (month.length == 1 ? '0' : '') + @@ -59,39 +47,33 @@ class TimeAgo { } String getTimeStringForChat(int timeStamp) { - final formatedTimeStamp = timeStamp * 1000; - final DateTime date = - DateTime.fromMillisecondsSinceEpoch(formatedTimeStamp); - final currentTimeStamp = DateTime.now().millisecondsSinceEpoch; + final DateTime date = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000); final Duration duration = DateTime.now().difference(date); + final int diffDays = duration.inDays + + (duration.inMinutes > + DateTime.now() + .difference(DateTime(DateTime.now().year, + DateTime.now().month, DateTime.now().day)) + .inMinutes + ? 1 + : 0); + final int diffMinutes = duration.inMinutes; - int diffDays = duration.inDays; - final diffMinutes = duration.inMinutes; var res; // 一个礼拜之内 if (diffDays > 0 && diffDays < 7) { - final String formatTodayZero = - DateFormat('yyyyMMdd').format(DateTime.now()); - final todayZero = DateTime.parse(formatTodayZero).millisecondsSinceEpoch; - final todayDiff = currentTimeStamp - todayZero; - - final isTwoDay = todayDiff < (diffMinutes - diffDays * 1440) * 60000; - if (isTwoDay) { - diffDays = diffDays + 1; - } - if (diffDays <= 2) { res = dayMap()[diffDays - 1]; } else { - res = daysMap()[date.weekday]; + res = weekdayMap()[date.weekday]; } } else if (diffDays >= 7) { //当年内 if (date.year == DateTime.now().year) { - res = getMounthDate(date); + res = getMonthDate(date); } else { - res = getYearMounthDate(date); + res = getYearMonthDate(date); } } else { if (diffMinutes > 1) { @@ -99,9 +81,9 @@ class TimeAgo { final String option2 = diffMinutes.toString(); res = TIM_t_para("{{option2}} 分钟前", "$option2 分钟前")(option2: option2); } else { - final prefix = date.hour > 12 ? TIM_t("下午") : TIM_t("上午"); - final timeStr = DateFormat('hh:mm').format(date); - res = "$prefix $timeStr"; + res = + "${date.hour}:${date.minute < 10 ? date.minute.toString() + "0" : date.minute}"; + // res = "$prefix $timeStr"; } } else { res = TIM_t("现在"); @@ -115,26 +97,27 @@ class TimeAgo { var nowTime = DateTime.now(); nowTime = DateTime(nowTime.year, nowTime.month, nowTime.day); var ftime = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000); - var preFix = ftime.hour >= 12 ? TIM_t("下午") : TIM_t("上午"); - final timeStr = DateFormat('hh:mm').format(ftime); - // 一年外 年月日 + 上/下午 + 时间 (12小时制) + // var preFix = ftime.hour >= 12 ? TIM_t("下午") : TIM_t("上午"); + final timeStr = + DateFormat('HH:mm').format(ftime); // Use 'HH:mm' for 24-hour format + // 一年外 年月日 + 时间 (24小时制) if (nowTime.year != ftime.year) { - return '${DateFormat('yyyy-MM-dd').format(ftime)} $preFix $timeStr'; + return '${DateFormat('yyyy-MM-dd').format(ftime)} $timeStr'; } - // 一年内一周外 月日 + 上/下午 + 时间 (12小时制) + // 一年内一周外 月日 + 时间 (24小时制) if (ftime.isBefore(nowTime.subtract(const Duration(days: 6)))) { - return '${DateFormat('MM-dd').format(ftime)} $preFix $timeStr'; + return '${DateFormat('MM-dd').format(ftime)} $timeStr'; } - // 一周内一天外 星期 + 上/下午 + 时间 (12小时制) + // 一周内一天外 星期 + 时间 (24小时制) if (ftime.isBefore(nowTime.subtract(const Duration(days: 1)))) { - return '${weekdayMap()[ftime.weekday]} $preFix $timeStr'; + return '${weekdayMap()[ftime.weekday]} $timeStr'; } - // 昨日 昨天 + 上/下午 + 时间 (12小时制) + // 昨日 昨天 + 时间 (24小时制) if (nowTime.day != ftime.day) { - String option2 = '$preFix $timeStr'; + String option2 = timeStr; return TIM_t_para("昨天 {{option2}}", "昨天 $option2")(option2: option2); } - // 同年月日 上/下午 + 时间 (12小时制) - return '$preFix $timeStr'; + // 同年月日 时间 (24小时制) + return timeStr; } } diff --git a/lib/ui/views/TIMUIKitAddFriend/tim_uikit_add_friend.dart b/lib/ui/views/TIMUIKitAddFriend/tim_uikit_add_friend.dart index 3ba37fc..aef87b5 100644 --- a/lib/ui/views/TIMUIKitAddFriend/tim_uikit_add_friend.dart +++ b/lib/ui/views/TIMUIKitAddFriend/tim_uikit_add_friend.dart @@ -1,5 +1,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; @@ -20,11 +23,15 @@ class TIMUIKitAddFriend extends StatefulWidget { /// The life cycle hooks for adding friends and contact business logic final AddFriendLifeCycle? lifeCycle; + + final VoidCallback? closeFunc; + const TIMUIKitAddFriend( {Key? key, this.isShowDefaultGroup = false, this.lifeCycle, - required this.onTapAlreadyFriendsItem}) + required this.onTapAlreadyFriendsItem, + this.closeFunc}) : super(key: key); @override @@ -45,6 +52,9 @@ class _TIMUIKitAddFriendState extends TIMUIKitState { Widget _searchResultItemBuilder( V2TimUserFullInfo friendInfo, TUITheme theme) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final faceUrl = friendInfo.faceUrl ?? ""; final userID = friendInfo.userID ?? ""; final String showName = @@ -74,14 +84,32 @@ class _TIMUIKitAddFriendState extends TIMUIKitState { return; } - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => SendApplication( - lifeCycle: widget.lifeCycle, - isShowDefaultGroup: widget.isShowDefaultGroup ?? false, - friendInfo: friendInfo, - model: _selfInfoViewModel))); + if (isDesktopScreen) { + if (widget.closeFunc != null) { + widget.closeFunc!(); + } + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.addFriend, + context: context, + width: MediaQuery.of(context).size.width * 0.3, + height: MediaQuery.of(context).size.width * 0.4, + title: TIM_t("添加好友"), + child: (closeFuncSendApplication) => SendApplication( + lifeCycle: widget.lifeCycle, + isShowDefaultGroup: widget.isShowDefaultGroup ?? false, + friendInfo: friendInfo, + model: _selfInfoViewModel), + ); + } else { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => SendApplication( + lifeCycle: widget.lifeCycle, + isShowDefaultGroup: widget.isShowDefaultGroup ?? false, + friendInfo: friendInfo, + model: _selfInfoViewModel))); + } }, child: Container( padding: const EdgeInsets.symmetric(vertical: 12), @@ -89,9 +117,9 @@ class _TIMUIKitAddFriendState extends TIMUIKitState { // crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - width: 48, - height: 48, - margin: const EdgeInsets.only(right: 12), + width: isDesktopScreen ? 38 : 48, + height: isDesktopScreen ? 38 : 48, + margin: const EdgeInsets.only(right: 16), child: Avatar(faceUrl: faceUrl, showName: showName), ), Column( @@ -99,7 +127,9 @@ class _TIMUIKitAddFriendState extends TIMUIKitState { children: [ Text( showName, - style: TextStyle(color: theme.darkTextColor, fontSize: 18), + style: TextStyle( + color: theme.darkTextColor, + fontSize: isDesktopScreen ? 16 : 18), ), const SizedBox( height: 4, diff --git a/lib/ui/views/TIMUIKitAddFriend/tim_uikit_send_application.dart b/lib/ui/views/TIMUIKitAddFriend/tim_uikit_send_application.dart index 883dbc7..6b0515b 100644 --- a/lib/ui/views/TIMUIKitAddFriend/tim_uikit_send_application.dart +++ b/lib/ui/views/TIMUIKitAddFriend/tim_uikit_send_application.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:tencent_im_base/tencent_im_base.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_friend_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; @@ -53,26 +54,9 @@ class _SendApplicationState extends TIMUIKitState { : userID) ?? ""; final option2 = widget.friendInfo.selfSignature ?? ""; - return Scaffold( - appBar: AppBar( - title: Text( - TIM_t("添加好友"), - style: TextStyle(color: theme.white, fontSize: 17), - ), - shadowColor: theme.white, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: IconThemeData( - color: theme.white, - ), - ), - body: SingleChildScrollView( + + Widget sendApplicationBody(){ + return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -95,7 +79,7 @@ class _SendApplicationState extends TIMUIKitState { Text( showName, style: - TextStyle(color: theme.darkTextColor, fontSize: 18), + TextStyle(color: theme.darkTextColor, fontSize: 18), ), const SizedBox( height: 4, @@ -103,16 +87,16 @@ class _SendApplicationState extends TIMUIKitState { Text( "ID: $userID", style: - TextStyle(fontSize: 13, color: theme.weakTextColor), + TextStyle(fontSize: 13, color: theme.weakTextColor), ), const SizedBox( height: 4, ), - Text( + if(TencentUtils.checkString(option2) != null)Text( TIM_t_para("个性签名: {{option2}}", "个性签名: $option2")( option2: option2), style: - TextStyle(fontSize: 13, color: theme.weakTextColor), + TextStyle(fontSize: 13, color: theme.weakTextColor), ), ], ) @@ -184,19 +168,19 @@ class _SendApplicationState extends TIMUIKitState { Container( color: theme.white, padding: - const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( TIM_t("分组"), style: - TextStyle(color: theme.darkTextColor, fontSize: 16), + TextStyle(color: theme.darkTextColor, fontSize: 16), ), Text( TIM_t("我的好友"), style: - TextStyle(color: theme.darkTextColor, fontSize: 16), + TextStyle(color: theme.darkTextColor, fontSize: 16), ) ], ), @@ -213,7 +197,7 @@ class _SendApplicationState extends TIMUIKitState { if (widget.lifeCycle?.shouldAddFriend != null && await widget.lifeCycle!.shouldAddFriend(userID, remark, - friendGroup, addWording, context) == + friendGroup, addWording, context) == false) { return; } @@ -246,7 +230,29 @@ class _SendApplicationState extends TIMUIKitState { ) ], ), + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: Container( + padding: const EdgeInsets.only(top: 10), + color: theme.weakBackgroundColor, + child: sendApplicationBody(), ), - ); + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("添加好友"), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), + ), + shadowColor: theme.white, + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + ), + ), + body: sendApplicationBody(), + )); } } diff --git a/lib/ui/views/TIMUIKitAddGroup/tim_uikit_add_group.dart b/lib/ui/views/TIMUIKitAddGroup/tim_uikit_add_group.dart index 4a96136..23d4798 100644 --- a/lib/ui/views/TIMUIKitAddGroup/tim_uikit_add_group.dart +++ b/lib/ui/views/TIMUIKitAddGroup/tim_uikit_add_group.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_group_life_cycle.dart'; @@ -19,8 +22,10 @@ class TIMUIKitAddGroup extends StatefulWidget { final Function(String groupID, V2TimConversation conversation) onTapExistGroup; + final VoidCallback? closeFunc; + const TIMUIKitAddGroup( - {Key? key, this.lifeCycle, required this.onTapExistGroup}) + {Key? key, this.lifeCycle, required this.onTapExistGroup, this.closeFunc}) : super(key: key); @override @@ -67,6 +72,8 @@ class _TIMUIKitAddGroupState extends TIMUIKitState { final groupID = groupInfo.groupID; final showName = groupInfo.groupName ?? groupID; final groupType = _getGroupType(groupInfo.groupType); + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return InkWell( onTap: () async { final V2TimConversation? groupConversation = @@ -76,16 +83,38 @@ class _TIMUIKitAddGroupState extends TIMUIKitState { type: TIMCallbackType.INFO, infoRecommendText: TIM_t("您已是群成员"), infoCode: 6660202)); + if (widget.closeFunc != null) { + widget.closeFunc!(); + } widget.onTapExistGroup(groupID, groupConversation); return; } - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => SendJoinGroupApplication( - lifeCycle: widget.lifeCycle, - groupInfo: groupInfo, - ))); + + if(isDesktopScreen){ + if (widget.closeFunc != null) { + widget.closeFunc!(); + } + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.addGroup, + context: context, + width: MediaQuery.of(context).size.width * 0.3, + height: MediaQuery.of(context).size.width * 0.4, + title: TIM_t("添加群聊"), + child: (closeFuncSendApplication) => SendJoinGroupApplication( + lifeCycle: widget.lifeCycle, + groupInfo: groupInfo, + ), + ); + }else{ + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => SendJoinGroupApplication( + lifeCycle: widget.lifeCycle, + groupInfo: groupInfo, + ))); + } + }, child: Container( padding: const EdgeInsets.symmetric(vertical: 12), @@ -93,9 +122,9 @@ class _TIMUIKitAddGroupState extends TIMUIKitState { // crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - width: 48, - height: 48, - margin: const EdgeInsets.only(right: 12), + width: isDesktopScreen ? 38 : 48, + height: isDesktopScreen ? 38 : 48, + margin: const EdgeInsets.only(right: 16), child: Avatar(faceUrl: faceUrl, showName: showName), ), Column( @@ -103,7 +132,7 @@ class _TIMUIKitAddGroupState extends TIMUIKitState { children: [ Text( showName, - style: const TextStyle(fontSize: 18), + style: TextStyle(fontSize: isDesktopScreen ? 16 : 18), ), Text( "ID: $groupID", diff --git a/lib/ui/views/TIMUIKitAddGroup/tim_uikit_send_application.dart b/lib/ui/views/TIMUIKitAddGroup/tim_uikit_send_application.dart index 178c192..1c64605 100644 --- a/lib/ui/views/TIMUIKitAddGroup/tim_uikit_send_application.dart +++ b/lib/ui/views/TIMUIKitAddGroup/tim_uikit_send_application.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/add_group_life_cycle.dart'; @@ -74,26 +75,9 @@ class _SendJoinGroupApplicationState final groupID = widget.groupInfo.groupID; final showName = widget.groupInfo.groupName ?? groupID; final option1 = _getGroupType(widget.groupInfo.groupType); - return Scaffold( - appBar: AppBar( - title: Text( - TIM_t("进群申请"), - style: TextStyle(color: theme.white, fontSize: 17), - ), - shadowColor: theme.white, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: IconThemeData( - color: theme.white, - ), - ), - body: SingleChildScrollView( + + Widget sendGroupApplicationBody(){ + return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -116,7 +100,7 @@ class _SendJoinGroupApplicationState Text( showName, style: - TextStyle(color: theme.darkTextColor, fontSize: 18), + TextStyle(color: theme.darkTextColor, fontSize: 18), ), const SizedBox( height: 4, @@ -124,7 +108,7 @@ class _SendJoinGroupApplicationState Text( "ID: $groupID", style: - TextStyle(fontSize: 13, color: theme.weakTextColor), + TextStyle(fontSize: 13, color: theme.weakTextColor), ), const SizedBox( height: 4, @@ -133,7 +117,7 @@ class _SendJoinGroupApplicationState TIM_t_para("群类型: {{option1}}", "群类型: $option1")( option1: option1), style: - TextStyle(fontSize: 12, color: theme.weakTextColor), + TextStyle(fontSize: 12, color: theme.weakTextColor), ), ], ) @@ -181,7 +165,26 @@ class _SendJoinGroupApplicationState ) ], ), + ); + } + + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: sendGroupApplicationBody(), + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("进群申请"), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), + ), + shadowColor: theme.white, + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + ), ), - ); + body: sendGroupApplicationBody(), + )); } } diff --git a/lib/ui/views/TIMUIKitBlackList/tim_uikit_black_list.dart b/lib/ui/views/TIMUIKitBlackList/tim_uikit_black_list.dart index bb97ccd..8c21604 100644 --- a/lib/ui/views/TIMUIKitBlackList/tim_uikit_black_list.dart +++ b/lib/ui/views/TIMUIKitBlackList/tim_uikit_black_list.dart @@ -7,6 +7,7 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendsh import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; @@ -50,35 +51,33 @@ class _TIMUIKitBlackListState extends TIMUIKitState { final theme = Provider.of(context).theme; final showName = _getShowName(friendInfo); final faceUrl = friendInfo.userProfile?.faceUrl ?? ""; - return Slidable( - endActionPane: ActionPane(motion: const DrawerMotion(), children: [ - SlidableAction( - onPressed: (context) async { - await _friendshipViewModel - .deleteFromBlockList([friendInfo.userID]); - }, - backgroundColor: theme.cautionColor ?? CommonColor.cautionColor, - foregroundColor: theme.white, - label: TIM_t("删除"), - autoClose: true, - ) - ]), - child: GestureDetector( + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + Widget itemWidget() { + return Material( + color: theme.wideBackgroundColor, + child: InkWell( onTap: () { if (widget.onTapItem != null) { widget.onTapItem!(friendInfo); } }, child: Container( - padding: const EdgeInsets.only(top: 10, left: 16), + padding: const EdgeInsets.only(top: 10, left: 16, right: 16), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), child: Row( children: [ Container( padding: const EdgeInsets.only(bottom: 12), margin: const EdgeInsets.only(right: 12), child: SizedBox( - height: 40, - width: 40, + height: isDesktopScreen ? 30 : 40, + width: isDesktopScreen ? 30 : 40, child: Avatar(faceUrl: faceUrl, showName: showName), ), ), @@ -86,19 +85,45 @@ class _TIMUIKitBlackListState extends TIMUIKitState { child: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.only(top: 10, bottom: 20), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), child: Text( showName, - style: TextStyle(color: theme.black, fontSize: 18), + style: TextStyle( + color: theme.black, fontSize: isDesktopScreen ? 14 : 18), ), - )) + )), + if (isDesktopScreen) + OutlinedButton( + onPressed: () { + _friendshipViewModel + .deleteFromBlockList([friendInfo.userID]); + }, + child: Text( + TIM_t("移出黑名单"), + style: TextStyle(color: theme.primaryColor), + )) ], ), ), + ), + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: itemWidget(), + defaultWidget: Slidable( + endActionPane: ActionPane(motion: const DrawerMotion(), children: [ + SlidableAction( + onPressed: (context) async { + await _friendshipViewModel + .deleteFromBlockList([friendInfo.userID]); + }, + backgroundColor: theme.cautionColor ?? CommonColor.cautionColor, + foregroundColor: theme.white, + label: TIM_t("删除"), + autoClose: true, + ) + ]), + child: itemWidget(), )); } @@ -106,10 +131,6 @@ class _TIMUIKitBlackListState extends TIMUIKitState { return widget.itemBuilder ?? _itemBuilder; } - @override - void initState() { - super.initState(); - } @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart index 56babcc..6b876bc 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart @@ -8,8 +8,8 @@ enum MessageListTongueType { none, toLatest, showUnread, - showPrevious, atMe, + showPrevious, atAll, } @@ -36,9 +36,9 @@ class TIMUIKitHistoryMessageListTongue extends TIMUIKitStatelessWidget { TIMUIKitHistoryMessageListTongue({ Key? key, - required this.previousCount, required this.valueType, required this.onClick, + required this.previousCount, required this.unreadCount, this.tongueItemBuilder, this.atNum = "", diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart index e03eea7..321c8f9 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart @@ -1,7 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; @@ -61,20 +61,22 @@ class _TIMUIKitHistoryMessageListTongueContainerState final screenHeight = MediaQuery.of(context).size.height; final offset = widget.scrollController.offset; final conversationUnreadCount = widget.model.getConversationUnreadCount(); - if (offset <= 0.0 && - conversationUnreadCount != 0) { + if (offset <= 0.0 && conversationUnreadCount != 0) { widget.model.showLatestUnread(); } if (widget.scrollController.offset <= widget.scrollController.position.minScrollExtent && - !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) { + !widget.scrollController.position.outOfRange && + !widget.model.haveMoreLatestData) { changePositionState(HistoryMessagePosition.bottom); } else if (widget.scrollController.offset <= screenHeight * 1.6 && widget.scrollController.offset > 0 && - !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) { + !widget.scrollController.position.outOfRange && + !widget.model.haveMoreLatestData) { changePositionState(HistoryMessagePosition.inTwoScreen); } else if (widget.scrollController.offset > screenHeight * 1.6 && - !widget.scrollController.position.outOfRange && !widget.model.haveMoreLatestData) { + !widget.scrollController.position.outOfRange && + !widget.model.haveMoreLatestData) { changePositionState(HistoryMessagePosition.awayTwoScreen); } } @@ -85,9 +87,8 @@ class _TIMUIKitHistoryMessageListTongueContainerState MessageListTongueType _getTongueValueType( List? groupAtInfoList) { - - if(globalModel.getMessageListPosition(widget.model.conversationID) == - HistoryMessagePosition.notShowLatest){ + if (globalModel.getMessageListPosition(widget.model.conversationID) == + HistoryMessagePosition.notShowLatest) { return MessageListTongueType.none; } if (groupAtInfoList != null && @@ -152,22 +153,24 @@ class _TIMUIKitHistoryMessageListTongueContainerState } else { widget.scrollToIndexBySeq(groupAtInfoList!.removeAt(0)!.seq); } - } else if ((widget.conversation.unreadCount ?? 0) > 20 && !isClickShowPrevious) { - try{ + } else if ((widget.conversation.unreadCount ?? 0) > 20 && + !isClickShowPrevious) { + try { isClickShowPrevious = true; final String? lastSeqString = widget.conversation.lastMessage?.seq; final int? lastSeq = - TencentUtils.checkString(lastSeqString) != null - ? int.parse(lastSeqString!) - : null; + TencentUtils.checkString(lastSeqString) != null + ? int.parse(lastSeqString!) + : null; final int? previousCount = widget.conversation.unreadCount; if (lastSeq != null && previousCount != null) { final targetSeq = lastSeq - previousCount; - await widget.model.loadListForSpecificMessage(seq: targetSeq); + await widget.model + .loadListForSpecificMessage(seq: targetSeq); // widget.scrollToIndexBySeq((targetSeq + 1).toString()); } - }catch(e){ + } catch (e) { // TODO: 这里后续加个弹窗提示客户,找消息失败了 } // widget.model.loadListForSpecificMessage(seq: count); diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_tongue_item.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_tongue_item.dart index 6c83348..5f0b663 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_tongue_item.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_tongue_item.dart @@ -21,7 +21,7 @@ class TIMUIKitTongueItem extends TIMUIKitStatelessWidget { final int previousCount; - TIMUIKitTongueItem( { + TIMUIKitTongueItem({ Key? key, required this.onClick, required this.valueType, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list.dart index f5f0dbb..b9239b5 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list.dart @@ -8,17 +8,14 @@ import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; - // ignore: unused_import import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_config.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/keepalive_wrapper.dart'; - import 'TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart'; import 'TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container.dart'; @@ -76,7 +73,8 @@ class TIMUIKitHistoryMessageList extends StatefulWidget { final V2TimMessage? initFindingMsg; /// use for load more message - final Future Function(String?, LoadDirection direction, [int?]) onLoadMore; + final Future Function(String?, LoadDirection direction, [int?]) + onLoadMore; /// configuration for list view final TIMUIKitHistoryMessageListConfig? mainHistoryListConfig; @@ -99,7 +97,7 @@ class TIMUIKitHistoryMessageList extends StatefulWidget { this.initFindingMsg, this.isAllowScroll = true, this.mainHistoryListConfig, - required this.conversation}) + required this.conversation}) : super(key: key); @override @@ -272,8 +270,8 @@ class _TIMUIKitHistoryMessageListState } else { if (widget.model.haveMoreData) { findingSeq = targetSeq; - widget.onLoadMore( - _getMessageId(widget.messageList.length - 1), LoadDirection.previous, singleLoadAmount); + widget.onLoadMore(_getMessageId(widget.messageList.length - 1), + LoadDirection.previous, singleLoadAmount); } else { showCantFindMsg(); } @@ -308,15 +306,15 @@ class _TIMUIKitHistoryMessageListState } } - List _getRecivedMessageList(int recivedMessageListCount) { - if (recivedMessageListCount == 0) { + List _getReceivedMessageList(int receivedMessageListCount) { + if (receivedMessageListCount == 0) { return []; } final haveTimeStampMessage = - widget.messageList[recivedMessageListCount]?.elemType == 11; + widget.messageList[receivedMessageListCount]?.elemType == 11; final endPoint = haveTimeStampMessage - ? recivedMessageListCount + 1 - : recivedMessageListCount; + ? receivedMessageListCount + 1 + : receivedMessageListCount; return widget.messageList.sublist(0, endPoint).reversed.toList(); } @@ -334,22 +332,23 @@ class _TIMUIKitHistoryMessageListState final globalModel = context.read(); final receivedNewMessageList = globalModel.receivedMessageListCount; final shouldShowUnreadMessage = receivedNewMessageList > 0; - final unreadMessageList = _getRecivedMessageList(receivedNewMessageList); + final unreadMessageList = _getReceivedMessageList(receivedNewMessageList); final readMessageList = messageList .sublist(unreadMessageList.length, messageList.length) .toList(); - final throteFunction = OptimizeUtils.multiThrottle((index, LoadDirection direction) async { + final throttleFunction = + OptimizeUtils.multiThrottle((index, LoadDirection direction) async { final msgID = TIMUIKitChatUtils.getMessageIDWithinIndex(readMessageList, index); await widget.onLoadMore(msgID, direction); }, 20); - final throteFunctionWithMsgID = OptimizeUtils.multiThrottle((msgID, LoadDirection direction) async { + final throttleFunctionWithMsgID = + OptimizeUtils.multiThrottle((msgID, LoadDirection direction) async { await widget.onLoadMore(msgID, direction); }, 200); - if (findingMsg != null) { _onScrollToIndex(findingMsg!); } else if (findingSeq != "") { @@ -360,167 +359,187 @@ class _TIMUIKitHistoryMessageListState return "${message?.msgID} - ${message?.timestamp} - ${message?.seq} -${message?.id}"; } - return Container( - color: theme.chatBgColor, - child: Stack( - alignment: Alignment.topCenter, - children: [ - CustomScrollView( - center: shouldShowUnreadMessage ? centerKey : null, - key: widget.mainHistoryListConfig?.key, - primary: widget.mainHistoryListConfig?.primary, - physics: (widget.isAllowScroll == false) - ? const NeverScrollableScrollPhysics() - : widget.mainHistoryListConfig?.physics, - // padding: widget.mainHistoryListConfig?.padding ?? EdgeInsets.zero, - // itemExtent: widget.mainHistoryListConfig?.itemExtent, - // prototypeItem: widget.mainHistoryListConfig?.prototypeItem, - cacheExtent: widget.mainHistoryListConfig?.cacheExtent ?? 1500, - semanticChildCount: - widget.mainHistoryListConfig?.semanticChildCount, - dragStartBehavior: - widget.mainHistoryListConfig?.dragStartBehavior ?? - DragStartBehavior.start, - keyboardDismissBehavior: - widget.mainHistoryListConfig?.keyboardDismissBehavior ?? - ScrollViewKeyboardDismissBehavior.manual, - restorationId: widget.mainHistoryListConfig?.restorationId, - clipBehavior: - widget.mainHistoryListConfig?.clipBehavior ?? Clip.hardEdge, - reverse: true, - shrinkWrap: !shouldShowUnreadMessage, + return Stack( + alignment: Alignment.topCenter, + children: [ + Scrollbar( controller: _autoScrollController, - slivers: [ - SliverPadding( - padding: - widget.mainHistoryListConfig?.padding ?? EdgeInsets.zero, - sliver: SliverList( - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - final messageItem = unreadMessageList[index]; - if(index == unreadMessageList.length - 1 && widget.model.haveMoreLatestData == true){ - throteFunctionWithMsgID(messageItem?.msgID ?? "", LoadDirection.latest); - } - return AutoScrollTag( - controller: _autoScrollController, - index: -index, - key: ValueKey( - getMessageIdentifier(messageItem, index)), - highlightColor: Colors.black.withOpacity(0.1), - child: KeepAliveWrapper( - keepAlive: messageItem?.elemType == - MessageElemType.V2TIM_ELEM_TYPE_SOUND, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16), - child: - _getMessageItemBuilder(messageItem))), - ); - }, - childCount: unreadMessageList.length, - findChildIndexCallback: (Key key) { - final ValueKey valueKey = - key as ValueKey; - final String data = valueKey.value; - final int index = unreadMessageList.indexWhere( - (element) => - getMessageIdentifier(element, 0) == data); - return index != -1 ? index : null; - })), - ), - SliverPadding( - padding: EdgeInsets.zero, - key: centerKey, - ), - SliverPadding( - padding: - widget.mainHistoryListConfig?.padding ?? EdgeInsets.zero, - sliver: SliverList( - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - final messageItem = readMessageList[index]; - if (index == readMessageList.length - 1) { - if (widget.model.haveMoreData) { - throteFunction(index, LoadDirection.previous); - return Column( - children: [ - LoadingAnimationWidget.staggeredDotsWave( - color: theme.weakTextColor ?? Colors.grey, - size: 28, - ), - AutoScrollTag( - controller: _autoScrollController, - index: -index, - key: ValueKey(getMessageIdentifier( - messageItem, index)), - highlightColor: - Colors.black.withOpacity(0.1), - child: KeepAliveWrapper( + child: CustomScrollView( + center: shouldShowUnreadMessage ? centerKey : null, + key: widget.mainHistoryListConfig?.key, + primary: widget.mainHistoryListConfig?.primary, + physics: (widget.isAllowScroll == false) + ? const NeverScrollableScrollPhysics() + : widget.mainHistoryListConfig?.physics, + // padding: widget.mainHistoryListConfig?.padding ?? EdgeInsets.zero, + // itemExtent: widget.mainHistoryListConfig?.itemExtent, + // prototypeItem: widget.mainHistoryListConfig?.prototypeItem, + cacheExtent: widget.mainHistoryListConfig?.cacheExtent ?? 1500, + semanticChildCount: + widget.mainHistoryListConfig?.semanticChildCount, + dragStartBehavior: + widget.mainHistoryListConfig?.dragStartBehavior ?? + DragStartBehavior.start, + keyboardDismissBehavior: + widget.mainHistoryListConfig?.keyboardDismissBehavior ?? + ScrollViewKeyboardDismissBehavior.manual, + restorationId: widget.mainHistoryListConfig?.restorationId, + clipBehavior: + widget.mainHistoryListConfig?.clipBehavior ?? Clip.hardEdge, + reverse: true, + shrinkWrap: !shouldShowUnreadMessage, + controller: _autoScrollController, + slivers: [ + SliverPadding( + padding: + widget.mainHistoryListConfig?.padding ?? EdgeInsets.zero, + sliver: SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, int index) { + final messageItem = unreadMessageList[index]; + if (index == unreadMessageList.length - 1 && + widget.model.haveMoreLatestData == true) { + throttleFunctionWithMsgID( + messageItem?.msgID ?? "", + LoadDirection.latest); + } + return AutoScrollTag( + controller: _autoScrollController, + index: -index, + key: ValueKey( + getMessageIdentifier(messageItem, index)), + highlightColor: Colors.black.withOpacity(0.1), + child: KeepAliveWrapper( + keepAlive: messageItem?.elemType == + MessageElemType.V2TIM_ELEM_TYPE_SOUND, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 16), + child: + _getMessageItemBuilder(messageItem))), + ); + }, + childCount: unreadMessageList.length, + findChildIndexCallback: (Key key) { + final ValueKey valueKey = + key as ValueKey; + final String data = valueKey.value; + final int index = unreadMessageList.indexWhere( + (element) => + getMessageIdentifier(element, 0) == data); + return index != -1 ? index : null; + })), + ), + SliverPadding( + padding: EdgeInsets.zero, + key: centerKey, + ), + SliverPadding( + padding: + widget.mainHistoryListConfig?.padding ?? EdgeInsets.zero, + sliver: Selector( + selector: (context, model) { + return model.haveMoreData; + }, + shouldRebuild: (previous, next) { + return previous != next; + }, + builder: (context, haveMoreData, child) { + return SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, int index) { + final messageItem = readMessageList[index]; + final isSelf = messageItem?.isSelf ?? true; + if (index == readMessageList.length - 1) { + if (haveMoreData) { + throttleFunction( + index, LoadDirection.previous); + return Column( + children: [ + LoadingAnimationWidget + .staggeredDotsWave( + color: theme.weakTextColor ?? + Colors.grey, + size: 28, + ), + AutoScrollTag( + controller: _autoScrollController, + index: -index, + key: ValueKey(getMessageIdentifier( + messageItem, index)), + highlightColor: + Colors.black.withOpacity(0.1), + child: KeepAliveWrapper( + keepAlive: messageItem + ?.elemType == + MessageElemType + .V2TIM_ELEM_TYPE_SOUND, + child: Container( + padding: const EdgeInsets + .symmetric( + horizontal: 16), + child: _getMessageItemBuilder( + messageItem))), + ), + ], + ); + } + } + if (index == 0 && + widget.model.haveMoreLatestData == true && + globalModel.receivedMessageListCount < 10) { + throttleFunction(index, LoadDirection.latest); + } + return AutoScrollTag( + controller: _autoScrollController, + index: -index, + key: ValueKey( + getMessageIdentifier(messageItem, index)), + highlightColor: Colors.black.withOpacity(0.1), + child: KeepAliveWrapper( keepAlive: messageItem?.elemType == MessageElemType.V2TIM_ELEM_TYPE_SOUND, child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16), + padding: EdgeInsets.only( + left: isSelf ? 0 : 16, + right: isSelf ? 16 : 0), child: _getMessageItemBuilder( - messageItem)), - ), - ), - ], - ); - } - } - if(index == 0 && widget.model.haveMoreLatestData == true && globalModel.receivedMessageListCount < 10){ - throteFunction(index, LoadDirection.latest); - } - return AutoScrollTag( - controller: _autoScrollController, - index: -index, - key: ValueKey( - getMessageIdentifier(messageItem, index)), - highlightColor: Colors.black.withOpacity(0.1), - child: KeepAliveWrapper( - keepAlive: messageItem?.elemType == - MessageElemType.V2TIM_ELEM_TYPE_SOUND, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16), - child: - _getMessageItemBuilder(messageItem))), - ); - }, - addAutomaticKeepAlives: true, - childCount: readMessageList.length, - findChildIndexCallback: (Key key) { - final ValueKey valueKey = - key as ValueKey; - final String data = valueKey.value; - final int index = readMessageList.indexWhere( - (element) => - getMessageIdentifier(element, 0) == data); - return index > -1 ? index : null; - } - )), - ), - ], - ), - TIMUIKitHistoryMessageListTongueContainer( - conversation: widget.conversation, - model: widget.model, - scrollController: _autoScrollController, - scrollToIndexBySeq: _onScrollToIndexBySeq, - groupAtInfoList: widget.groupAtInfoList, - tongueItemBuilder: widget.tongueItemBuilder, - ), - if (loadingPlace == LoadingPlace.top) - Positioned( - top: 8, - child: LoadingAnimationWidget.staggeredDotsWave( - color: theme.weakTextColor ?? Colors.grey, - size: 28, - ), + messageItem))), + ); + }, + childCount: readMessageList.length, + findChildIndexCallback: (Key key) { + final ValueKey valueKey = + key as ValueKey; + final String data = valueKey.value; + final int index = readMessageList.indexWhere( + (element) => + getMessageIdentifier(element, 0) == + data); + return index > -1 ? index : null; + })); + }, + ), + ), + ], + )), + TIMUIKitHistoryMessageListTongueContainer( + conversation: widget.conversation, + model: widget.model, + scrollController: _autoScrollController, + scrollToIndexBySeq: _onScrollToIndexBySeq, + groupAtInfoList: widget.groupAtInfoList, + tongueItemBuilder: widget.tongueItemBuilder, + ), + if (loadingPlace == LoadingPlace.top) + Positioned( + top: 8, + child: LoadingAnimationWidget.staggeredDotsWave( + color: theme.weakTextColor ?? Colors.grey, + size: 28, ), - ], - ), + ), + ], ); } } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart index d626b6f..6383cab 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart @@ -1,20 +1,22 @@ -// ignore_for_file: non_constant_identifier_names - import 'dart:convert'; +import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:provider/provider.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/forward_message_screen.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_super_tooltip/tencent_super_tooltip.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; - import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; @@ -30,9 +32,7 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageIt import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; -import 'package:tencent_cloud_chat_uikit/ui/widgets/loading.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart'; - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart'; @@ -66,6 +66,15 @@ typedef MessageItemContent = Widget? Function( VoidCallback clearJump, ); +class MessageHoverControlItem { + String name; + Widget icon; + ValueChanged onClick; + + MessageHoverControlItem( + {required this.name, required this.icon, required this.onClick}); +} + class MessageItemBuilder { /// text message builder final MessageItemContent? textMessageItemBuilder; @@ -125,6 +134,19 @@ class MessageItemBuilder { }); } +class MessageToolTipItem { + final String label; + final String id; + final String iconImageAsset; + final VoidCallback onClick; + + MessageToolTipItem( + {required this.label, + required this.id, + required this.iconImageAsset, + required this.onClick}); +} + class ToolTipsConfig { final bool showReplyMessage; final bool showMultipleChoiceMessage; @@ -135,6 +157,8 @@ class ToolTipsConfig { final bool showTranslation; final Widget? Function(V2TimMessage message, Function() closeTooltip, [Key? key, BuildContext? context])? additionalItemBuilder; + List Function( + V2TimMessage message, Function() closeTooltip)? additionalMessageToolTips; ToolTipsConfig( {this.showDeleteMessage = true, @@ -144,7 +168,9 @@ class ToolTipsConfig { this.showTranslation = true, this.showCopyMessage = true, this.showForwardMessage = true, - this.additionalItemBuilder}); + this.additionalMessageToolTips, + @Deprecated("Please use `additionalMessageToolTips` instead. You are now only expected to specify the data, rather than providing a whole widget. This makes usage easier, as you no longer need to worry about the UI display.") + this.additionalItemBuilder}); } class TIMUIKitHistoryMessageListItem extends StatefulWidget { @@ -152,7 +178,8 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget { final V2TimMessage message; /// tap remote user avatar callback function - final void Function(String userID)? onTapForOthersPortrait; + final void Function(String userID, TapDownDetails tapDetails)? + onTapForOthersPortrait; /// the function use for reply message, when click replied message can scroll to it. final Function? onScrollToIndex; @@ -167,7 +194,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget { /// message item builder, works for customize all message types and row layout. final MessageItemBuilder? messageItemBuilder; - /// controll avatart hide or show + /// Control avatar hide or show final bool showAvatar; /// message sending status @@ -185,7 +212,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget { /// allow avatar can tap final bool allowAvatarTap; - /// allow notifi user when send reply message + /// Auto mention user when send reply message final bool allowAtUserWhenReply; @Deprecated( @@ -260,7 +287,7 @@ class TIMUIKitHistoryMessageListItem extends StatefulWidget { this.bottomRowBuilder, this.isUseDefaultEmoji = false, this.customEmojiStickerList = const [], - this.textFieldController}) + this.textFieldController}) : super(key: key); @override @@ -306,13 +333,17 @@ class _TIMUIKItHistoryMessageListItemState extends TIMUIKitState with TickerProviderStateMixin { SuperTooltip? tooltip; + // ignore: unused_field final MessageService _messageService = serviceLocator(); final TUISelfInfoViewModel selfInfoModel = serviceLocator(); final TUIThemeViewModel themeModel = serviceLocator(); + // bool isChecked = false; final GlobalKey _key = GlobalKey(); + bool isShowWideToolTip = false; + TapDownDetails? _tapDetails; closeTooltip() { tooltip?.close(); @@ -323,8 +354,11 @@ class _TIMUIKItHistoryMessageListItemState message.cloudCustomData != null && message.cloudCustomData != ""; if (hasCustomData) { try { - final CloudCustomData messageCloudCustomData = - CloudCustomData.fromJson(json.decode(message.cloudCustomData!)); + final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson( + json.decode( + TencentUtils.checkString(message.cloudCustomData) != null + ? message.cloudCustomData! + : "{}")); if (messageCloudCustomData.messageReply != null) { MessageRepliedData.fromJson(messageCloudCustomData.messageReply!); return true; @@ -343,7 +377,7 @@ class _TIMUIKItHistoryMessageListItemState final isShowJump = (model.jumpMsgID == messageItem.msgID) && (messageItem.msgID?.isNotEmpty ?? false); final MessageItemBuilder? messageItemBuilder = widget.messageItemBuilder; - final isFromSelf = messageItem.isSelf ?? false; + final isFromSelf = messageItem.isSelf ?? true; void clearJump() { Future.delayed(const Duration(milliseconds: 100), () { model.jumpMsgID = ""; @@ -382,7 +416,7 @@ class _TIMUIKItHistoryMessageListItemState message: messageItem, soundElem: messageItem.soundElem!, msgID: messageItem.msgID ?? "", - isFromSelf: messageItem.isSelf ?? false, + isFromSelf: messageItem.isSelf ?? true, clearJump: clearJump, isShowJump: isShowJump, localCustomInt: messageItem.localCustomInt, @@ -410,6 +444,8 @@ class _TIMUIKItHistoryMessageListItemState fontStyle: widget.themeData?.messageTextStyle, backgroundColor: widget.themeData?.messageBackgroundColor, textPadding: widget.textPadding, + isUseDefaultEmoji: widget.isUseDefaultEmoji, + customEmojiStickerList: widget.customEmojiStickerList, chatModel: model, isShowMessageReaction: widget.isUseMessageReaction, ); @@ -424,7 +460,7 @@ class _TIMUIKItHistoryMessageListItemState return TIMUIKitTextElem( chatModel: model, message: messageItem, - isFromSelf: messageItem.isSelf ?? false, + isFromSelf: messageItem.isSelf ?? true, clearJump: clearJump, isShowJump: isShowJump, borderRadius: widget.themeData?.messageBorderRadius, @@ -464,7 +500,7 @@ class _TIMUIKItHistoryMessageListItemState message: messageItem, messageID: messageItem.msgID, fileElem: messageItem.fileElem, - isSelf: messageItem.isSelf ?? false, + isSelf: messageItem.isSelf ?? true, clearJump: clearJump, isShowJump: isShowJump, isShowMessageReaction: widget.isUseMessageReaction, @@ -527,7 +563,7 @@ class _TIMUIKItHistoryMessageListItemState )!; } return TIMUIKitMergerElem( - messageItemBuilder: messageItemBuilder, + messageItemBuilder: messageItemBuilder, model: model, isShowJump: isShowJump, clearJump: clearJump, @@ -535,7 +571,7 @@ class _TIMUIKItHistoryMessageListItemState isShowMessageReaction: widget.isUseMessageReaction, mergerElem: messageItem.mergerElem!, messageID: messageItem.msgID ?? "", - isSelf: messageItem.isSelf ?? false); + isSelf: messageItem.isSelf ?? true); default: return Text(TIM_t("[未知消息]")); } @@ -545,8 +581,9 @@ class _TIMUIKItHistoryMessageListItemState final messageItem = widget.message; return Container( padding: const EdgeInsets.only(bottom: 20), - child: - TIMUIKitGroupTipsElem(groupTipsElem: messageItem.groupTipsElem!, groupMemberList: model.groupMemberList ?? [])); + child: TIMUIKitGroupTipsElem( + groupTipsElem: messageItem.groupTipsElem!, + groupMemberList: model.groupMemberList ?? [])); } Widget _selfRevokeEditMessageBuilder(theme, model) { @@ -611,12 +648,11 @@ class _TIMUIKItHistoryMessageListItemState width: 100, child: Container( decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - const Color(0x00C0E1FF), - theme.primaryColor ?? CommonColor.lightPrimaryColor - ]), - ) - ), + gradient: LinearGradient(colors: [ + const Color(0x00C0E1FF), + theme.primaryColor ?? CommonColor.lightPrimaryColor + ]), + )), ), ), Text( @@ -635,12 +671,11 @@ class _TIMUIKItHistoryMessageListItemState width: 100, child: Container( decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.primaryColor ?? CommonColor.primaryColor, - const Color(0x00C0E1FF), - ]), - ) - ), + gradient: LinearGradient(colors: [ + theme.primaryColor ?? CommonColor.primaryColor, + const Color(0x00C0E1FF), + ]), + )), ), ), ], @@ -648,15 +683,17 @@ class _TIMUIKItHistoryMessageListItemState ); } - bool isRevokable(int timestamp) => + bool isRevocable(int timestamp) => (DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < 120; - _onLongPress( + _onOpenToolTip( c, V2TimMessage message, TUIChatSeparateViewModel model, TUITheme theme, TapDownDetails? details, + bool? isFromWideTooltip, + bool? isShowMoreSticker, ) { if (tooltip != null && tooltip!.isOpen) { tooltip!.close(); @@ -665,29 +702,40 @@ class _TIMUIKItHistoryMessageListItemState tooltip = null; final screenHeight = MediaQuery.of(context).size.height; - if (context.size!.height + 180 > screenHeight && !PlatformUtils().isWeb) { - initTools( - context: c, - isLongMessage: true, - model: model, - details: details, - theme: theme, - ); - if (widget.onScrollToIndexBegin != null) { - widget.onScrollToIndexBegin!(message); - } - Future.delayed(const Duration(milliseconds: 500), () { - tooltip!.show(c); - }); - } else { - initTools( + final screenWidth = MediaQuery.of(context).size.width; + final isLongMessage = + context.size!.height + 350 > screenHeight && PlatformUtils().isMobile; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final tapDetails = + (isDesktopScreen || isLongMessage) ? (details ?? _tapDetails) : details; + final isSelf = message.isSelf ?? true; + + final targetWidth = + min(MediaQuery.of(context).size.width * 0.84, 350).toDouble(); + final double dx = !isSelf + ? min(tapDetails?.globalPosition.dx ?? targetWidth, + screenWidth - targetWidth) + : max(tapDetails?.globalPosition.dx ?? targetWidth, targetWidth) + .toDouble(); + final double dy = min( + tapDetails?.globalPosition.dy ?? MediaQuery.of(context).size.height, + MediaQuery.of(context).size.height - 320) + .toDouble(); + final finalTapDetail = tapDetails != null + ? TapDownDetails( + globalPosition: Offset(dx, dy), + ) + : null; + + initTools( context: c, model: model, - details: details, + isShowMoreSticker: isShowMoreSticker, + details: finalTapDetail, theme: theme, - ); - tooltip!.show(c, targetCenter: details?.globalPosition); - } + isFromWideToolTip: isFromWideTooltip); + tooltip!.show(c, targetCenter: finalTapDetail?.globalPosition); } _clickOnCurrentSticker(int sticker) async { @@ -711,8 +759,15 @@ class _TIMUIKItHistoryMessageListItemState bool isLongMessage = false, required TUIChatSeparateViewModel model, TUITheme? theme, - TapDownDetails? details}) { - final isSelf = widget.message.isSelf ?? false; + bool? isShowMoreSticker, + TapDownDetails? details, + bool? isFromWideToolTip}) { + final isUseMessageReaction = widget.message.elemType == 2 + ? false + : model.chatConfig.isUseMessageReaction; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final isSelf = widget.message.isSelf ?? true; double arrowTipDistance = 30; double arrowBaseWidth = 10; double arrowLength = 10; @@ -727,12 +782,12 @@ class _TIMUIKItHistoryMessageListItemState if (details != null && box != null) { double screenWidth = MediaQuery.of(context).size.width; final mousePosition = details.globalPosition; - hasArrow = false; + hasArrow = isDesktopScreen ? false : true; arrowTipDistance = 0; arrowBaseWidth = 0; arrowLength = 0; popupDirection = TooltipDirection.down; - if (isSelf) { + if (isSelf || (isFromWideToolTip ?? false)) { right = screenWidth - mousePosition.dx; } else { left = mousePosition.dx; @@ -744,14 +799,16 @@ class _TIMUIKItHistoryMessageListItemState Offset offset = box.localToGlobal(Offset.zero); double boxWidth = box.size.width; if (isSelf) { - right = screenWidth - offset.dx - boxWidth; + right = screenWidth - + offset.dx - + ((isUseMessageReaction) ? boxWidth : (boxWidth / 1.3)); } else { left = offset.dx; } if (offset.dy < 300 && !isLongMessage && viewInsetsBottom == 0) { selectEmojiPanelPosition = SelectEmojiPanelPosition.up; popupDirection = TooltipDirection.down; - } else if(viewInsetsBottom != 0 && offset.dy < 220){ + } else if (viewInsetsBottom != 0 && offset.dy < 220) { selectEmojiPanelPosition = SelectEmojiPanelPosition.up; popupDirection = TooltipDirection.down; } @@ -773,16 +830,15 @@ class _TIMUIKItHistoryMessageListItemState borderColor: theme?.white ?? Colors.white, backgroundColor: theme?.white ?? Colors.white, shadowColor: Colors.black26, - hasShadow: true, + hasShadow: isDesktopScreen ? false : true, borderWidth: 1.0, showCloseButton: ShowCloseButton.none, touchThroughAreaShape: ClipAreaShape.rectangle, content: TIMUIKitMessageTooltip( model: model, + isShowMoreSticker: isShowMoreSticker ?? false, toolTipsConfig: widget.toolTipsConfig, - isUseMessageReaction: widget.message.elemType == 2 - ? false - : model.chatConfig.isUseMessageReaction, + isUseMessageReaction: isUseMessageReaction, message: widget.message, allowAtUserWhenReply: widget.allowAtUserWhenReply, onLongPressForOthersHeadPortrait: @@ -797,12 +853,6 @@ class _TIMUIKItHistoryMessageListItemState ); } - double getMaxWidth(isSelect) { - final size = MediaQuery.of(context).size; - final width = size.width; - return width - (isSelect ? 180 : 150); - } - Widget _getMessageItemBuilder(V2TimMessage message, int? messageStatues, TUIChatSeparateViewModel model) { final messageBuilder = _messageItemBuilder; @@ -811,7 +861,7 @@ class _TIMUIKItHistoryMessageListItemState } // 弹出对话框 - Future showResendMsgFailDialg(BuildContext context) { + Future showResendMsgFailDialog(BuildContext context) { return showDialog( context: context, builder: (context) { @@ -837,6 +887,117 @@ class _TIMUIKItHistoryMessageListItemState ); } + @override + void dispose() { + super.dispose(); + if (tooltip?.isOpen ?? false) { + tooltip?.close(); + } + } + + bool isVoteMessage(V2TimMessage message) { + bool isvote = false; + V2TimCustomElem? custom = message.customElem; + + if (custom != null) { + String? data = custom.data; + if (data != null && data.isNotEmpty) { + try { + Map mapData = json.decode(data); + if (mapData["businessID"] == "group_poll") { + isvote = true; + } + } catch (err) { + // err + } + } + } + return isvote; + } + + List getMessageHoverControlBar( + TUIChatSeparateViewModel model, TUITheme theme) { + return [ + if (widget.isUseMessageReaction ?? false) + MessageHoverControlItem( + name: TIM_t("表情回应"), + icon: Icon( + Icons.emoji_emotions, + size: 13, + color: hexToColor("8f959e"), + ), + onClick: (details) { + _onOpenToolTip( + context, widget.message, model, theme, details, true, true); + }, + ), + if (widget.toolTipsConfig?.showReplyMessage ?? true) + MessageHoverControlItem( + name: TIM_t("回复"), + icon: Icon( + Icons.message, + size: 13, + color: hexToColor("8f959e"), + ), + onClick: (_) { + model.repliedMessage = widget.message; + if (widget.allowAtUserWhenReply && + widget.onLongPressForOthersHeadPortrait != null && + !(widget.message.isSelf ?? true)) { + widget.onLongPressForOthersHeadPortrait!( + widget.message.sender, widget.message.nickName); + } + }, + ), + if ((widget.toolTipsConfig?.showForwardMessage ?? true) && + !isVoteMessage(widget.message)) + MessageHoverControlItem( + name: TIM_t("转发"), + icon: Icon( + Icons.send, + size: 13, + color: hexToColor("8f959e"), + ), + onClick: (_) { + model.addToMultiSelectedMessageList(widget.message); + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.forward, + context: context, + title: TIM_t("转发"), + submitWidget: Text(TIM_t("发送")), + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.8, + onSubmit: () { + forwardMessageScreenKey.currentState?.handleForwardMessage(); + }, + child: (onClose) => Container( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: ForwardMessageScreen( + conversationType: ConvType.c2c, + key: forwardMessageScreenKey, + onClose: onClose, + model: model, + ), + ), + theme: theme); + }, + ), + MessageHoverControlItem( + name: TIM_t("更多"), + icon: Icon( + Icons.more_horiz, + size: 13, + color: hexToColor("8f959e"), + ), + onClick: (details) { + _onOpenToolTip( + context, widget.message, model, theme, details, true, false); + }, + ), + ...?model.chatConfig.additionalDesktopMessageHoverBarItem + ]; + } + _onMsgSendFailIconTap(V2TimMessage message, TUIChatSeparateViewModel model) { final convID = model.conversationID; final convType = model.conversationType; @@ -848,12 +1009,99 @@ class _TIMUIKItHistoryMessageListItemState context); } - @override - void dispose() { - super.dispose(); - if (tooltip?.isOpen ?? false) { - tooltip?.close(); - } + Widget renderHoverTipAndReadStatus(TUIChatSeparateViewModel model, + bool isSelf, V2TimMessage message, bool isPeerRead, TUITheme theme) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final wideHoverTipList = getMessageHoverControlBar(model, theme); + final lastItemName = wideHoverTipList.last.name; + return Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (isDesktopScreen && isShowWideToolTip) + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + border: Border.all(color: hexToColor("d9dde0"), width: 1)), + margin: const EdgeInsets.symmetric(horizontal: 4), + child: Row( + children: wideHoverTipList + .map((e) => Tooltip( + message: e.name, + preferBelow: false, + textStyle: TextStyle(fontSize: 12, color: theme.white), + child: Row( + children: [ + InkWell( + onTapDown: e.onClick, + child: SizedBox( + width: 22, + height: 22, + child: e.icon, + ), + ), + if (lastItemName != e.name) + SizedBox( + width: 1, + height: 22, + child: Container( + color: theme.weakDividerColor, + ), + ) + ], + ), + )) + .toList(), + ), + ), + if (!isDesktopScreen || !isShowWideToolTip) + const SizedBox( + height: 24, + ), + if (isSelf && + message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL) + Container( + padding: const EdgeInsets.only(bottom: 3), + margin: const EdgeInsets.only(right: 6), + child: GestureDetector( + onTap: () async { + final reSend = await showResendMsgFailDialog(context); + if (reSend != null) { + _onMsgSendFailIconTap(message, model); + } + }, + child: Icon(Icons.error, color: theme.cautionColor, size: 18), + )), + if (model.chatConfig.isShowReadingStatus && + widget.showMessageReadRecipt && + model.conversationType == ConvType.c2c && + isSelf && + (message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC || + message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING)) + Container( + padding: const EdgeInsets.only(bottom: 3), + margin: const EdgeInsets.only(right: 6), + child: Text( + isPeerRead ? TIM_t("已读") : TIM_t("未读"), + style: TextStyle( + color: theme.chatMessageItemUnreadStatusTextColor, + fontSize: 12), + ), + ), + if (model.chatConfig.isShowGroupReadingStatus && + model.chatConfig.isShowGroupMessageReadReceipt && + model.conversationType == ConvType.group && + isSelf && + (message.status == MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC || + message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING)) + TIMUIKitMessageReadReceipt( + messageItem: widget.message, + onTapAvatar: widget.onTapForOthersPortrait, + ), + ], + ); } @override @@ -865,7 +1113,7 @@ class _TIMUIKItHistoryMessageListItemState final TUITheme theme = value.theme; final message = widget.message; final msgType = message.elemType; - final isSelf = message.isSelf ?? false; + final isSelf = message.isSelf ?? true; final msgStatus = message.status; final isGroupTipsMsg = msgType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS; @@ -880,10 +1128,12 @@ class _TIMUIKItHistoryMessageListItemState isGroupMessage && model.chatConfig.isShowSelfNameInGroup; final isShowNickNameForOthers = isGroupMessage && model.chatConfig.isShowOthersNameInGroup; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (isTimeDivider) { return _timeDividerBuilder(theme, message.timestamp ?? 0, model); } - if(isLatestDivider){ + if (isLatestDivider) { return _latestDividerBuilder(theme); } void clearJump() { @@ -908,7 +1158,7 @@ class _TIMUIKItHistoryMessageListItemState if (isRevokedMsg) { final displayName = isSelf ? TIM_t("您") : message.nickName ?? message.sender; - return isSelf && isRevokeEditable && isRevokable(message.timestamp!) + return isSelf && isRevokeEditable && isRevocable(message.timestamp!) ? _selfRevokeEditMessageBuilder(theme, model) : _revokedMessageBuilder(theme, displayName ?? ""); } @@ -938,7 +1188,7 @@ class _TIMUIKItHistoryMessageListItemState children: [ if (model.isMultiSelect) Container( - margin: const EdgeInsets.only(right: 12, top: 10), + margin: EdgeInsets.only(right: 12, top: 10, left: isSelf ? 16 : 0), child: CheckBoxButton( isChecked: model.multiSelectedMessageList.contains(message), onChanged: (value) { @@ -951,260 +1201,250 @@ class _TIMUIKItHistoryMessageListItemState ), ), Expanded( - child: GestureDetector( - behavior: - model.isMultiSelect ? HitTestBehavior.translucent : null, - onTap: () { - if (model.isMultiSelect) { - final checked = - model.multiSelectedMessageList.contains(message); - if (checked) { - model.removeFromMultiSelectedMessageList(message); - } else { - model.addToMultiSelectedMessageList(message); - } + child: MouseRegion( + onEnter: (_) { + if (isDesktopScreen) { + setState(() { + isShowWideToolTip = true; + }); } }, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: - isSelf ? MainAxisAlignment.end : MainAxisAlignment.start, - children: [ - if (!isSelf && widget.showAvatar) - GestureDetector( - onTap: () { - if (widget.onTapForOthersPortrait != null && - widget.allowAvatarTap) { - widget - .onTapForOthersPortrait!(message.sender ?? ""); - } - }, - onLongPress: () { - if (widget.onLongPressForOthersHeadPortrait != - null) {} - widget.onLongPressForOthersHeadPortrait!( - message.sender, message.nickName); - }, - child: widget.userAvatarBuilder != null - ? widget.userAvatarBuilder!(context, message) - : Container( - margin: (isSelf && isShowNickNameForSelf) || - (!isSelf && isShowNickNameForOthers) - ? const EdgeInsets.only(top: 2) - : null, - child: SizedBox( - width: 40, - height: 40, - child: Avatar( - faceUrl: message.faceUrl ?? "", - showName: - MessageUtils.getDisplayName(message), - ), - ), - ), - ), - Container( - margin: widget.showAvatar - ? (isSelf - ? const EdgeInsets.only(right: 13) - : const EdgeInsets.only(left: 13)) - : null, - child: Column( - crossAxisAlignment: isSelf - ? CrossAxisAlignment.end - : CrossAxisAlignment.start, - children: [ - if ((isSelf && isShowNickNameForSelf) || - (!isSelf && isShowNickNameForOthers)) - widget.topRowBuilder != null - ? widget.topRowBuilder!(context, message) - : Container( - margin: const EdgeInsets.only(bottom: 4), - child: ConstrainedBox( - constraints: BoxConstraints( - maxWidth: MediaQuery.of(context) - .size - .width / - 1.7), - child: Text( - MessageUtils.getDisplayName(message), - overflow: TextOverflow.ellipsis, - style: widget - .themeData?.nickNameTextStyle ?? - TextStyle( - fontSize: 12, - color: theme.weakTextColor), - ), - )), - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - if (model.chatConfig.isShowReadingStatus && - widget.showMessageReadRecipt && - model.conversationType == ConvType.c2c && - isSelf && - message.status == - MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC) - Container( - padding: const EdgeInsets.only(bottom: 3), - margin: const EdgeInsets.only(right: 6), - child: Text( - isPeerRead ? TIM_t("已读") : TIM_t("未读"), - style: TextStyle( - color: theme - .chatMessageItemUnreadStatusTextColor, - fontSize: 12), - ), - ), - if (model.chatConfig.isShowGroupReadingStatus && - model.chatConfig - .isShowGroupMessageReadReceipt && - model.conversationType == ConvType.group && - isSelf && - message.status == - MessageStatus.V2TIM_MSG_STATUS_SEND_SUCC) - TIMUIKitMessageReadReceipt( - messageItem: widget.message, - onTapAvatar: widget.onTapForOthersPortrait, - ), - if (widget.showMessageSending && - isSelf && - message.status == - MessageStatus.V2TIM_MSG_STATUS_SENDING) - Container( - padding: const EdgeInsets.only(bottom: 3), - margin: const EdgeInsets.only(right: 6), - child: const Loading(), - ), - if (isSelf && - message.status == - MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL) - Container( - padding: const EdgeInsets.only(bottom: 3), - margin: const EdgeInsets.only(right: 6), - child: GestureDetector( - onTap: () async { - final reSend = - await showResendMsgFailDialg( - context); - if (reSend != null) { - _onMsgSendFailIconTap(message, model); - } - }, - child: Icon(Icons.error, - color: theme.cautionColor, size: 18), - )), - Container( - constraints: BoxConstraints( - // maxWidth: getMaxWidth(false), - // maxWidth: getMaxWidth(false), - maxWidth: constraints.maxWidth * 0.8, - ), - child: Builder(builder: (context) { - return Column( - crossAxisAlignment: - (message.isSelf ?? false) - ? CrossAxisAlignment.end - : CrossAxisAlignment.start, - children: [ - GestureDetector( - child: IgnorePointer( - ignoring: model.isMultiSelect, - child: _getMessageItemBuilder( - message, message.status, model)), - onSecondaryTapDown: (details) { - if (PlatformUtils().isWeb) { - if (widget.allowLongPress) { - _onLongPress( - context, - message, - model, - theme, - details, - ); - } - if (widget.onLongPress != null) { - widget.onLongPress!(context, message); - } - } - }, - onLongPress: () { - if (widget.allowLongPress) { - _onLongPress( - context, - message, - model, - theme, - null, - ); - } - if (widget.onLongPress != null) { - widget.onLongPress!(context, message); - } - }, - ), - Container( - color: theme.white, - child: TIMUIKitTextTranslationElem( - message: message, - isUseDefaultEmoji: widget.isUseDefaultEmoji, - customEmojiStickerList: widget.customEmojiStickerList, - isFromSelf: message.isSelf ?? false, - isShowJump: false, - clearJump: () {}, - chatModel: model), - ) - ], - ); - }), - ), - if (!isSelf && - message.elemType == - MessageElemType.V2TIM_ELEM_TYPE_SOUND && - message.localCustomInt != null && - message.localCustomInt != - HistoryMessageDartConstant.read) - Padding( - padding: const EdgeInsets.only( - left: 5, bottom: 12), - child: Icon(Icons.circle, - color: theme.cautionColor, size: 10)), - ], - ), - if (widget.bottomRowBuilder != null) - widget.bottomRowBuilder!(context, message) - ], - ), - ), - if (widget.message.elemType == 6 && isDownloadWaiting) - Container( - margin: const EdgeInsets.only(top: 24, left: 6), - child: LoadingAnimationWidget.threeArchedCircle( - color: theme.weakTextColor ?? Colors.grey, - size: 20, - ), - ), - if (isSelf && widget.showAvatar) - widget.userAvatarBuilder != null - ? widget.userAvatarBuilder!(context, message) - : SizedBox( - width: 40, - height: 40, - child: GestureDetector( - onTap: () { + onExit: (_) { + if (isDesktopScreen) { + setState(() { + isShowWideToolTip = false; + }); + } + }, + child: GestureDetector( + behavior: + model.isMultiSelect ? HitTestBehavior.translucent : null, + onTap: () { + if (model.isMultiSelect) { + final checked = + model.multiSelectedMessageList.contains(message); + if (checked) { + model.removeFromMultiSelectedMessageList(message); + } else { + model.addToMultiSelectedMessageList(message); + } + } + }, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: isSelf + ? MainAxisAlignment.end + : MainAxisAlignment.start, + children: [ + if (!isSelf && widget.showAvatar) + InkWell( + onLongPress: () { + if (widget.onLongPressForOthersHeadPortrait != + null) {} + if (model.chatConfig.isAllowLongPressAvatarToAt) { + widget.onLongPressForOthersHeadPortrait!( + message.sender, message.nickName); + } + }, + onTapDown: isDesktopScreen + ? (details) { if (widget.onTapForOthersPortrait != null && widget.allowAvatarTap) { widget.onTapForOthersPortrait!( - message.sender ?? ""); + message.sender ?? "", details); + } + } + : null, + onTap: isDesktopScreen + ? null + : () { + if (widget.onTapForOthersPortrait != null && + widget.allowAvatarTap) { + widget.onTapForOthersPortrait!( + message.sender ?? "", TapDownDetails()); } }, - child: Avatar( - faceUrl: message.faceUrl ?? "", - showName: - MessageUtils.getDisplayName(message)), - ), + child: widget.userAvatarBuilder != null + ? widget.userAvatarBuilder!(context, message) + : Container( + margin: (isSelf && isShowNickNameForSelf) || + (!isSelf && isShowNickNameForOthers) + ? const EdgeInsets.only(top: 2) + : null, + child: SizedBox( + width: 40, + height: 40, + child: Avatar( + faceUrl: message.faceUrl ?? "", + showName: + MessageUtils.getDisplayName(message), + ), + ), + ), + ), + Container( + margin: widget.showAvatar + ? (isSelf + ? const EdgeInsets.only(right: 13) + : const EdgeInsets.only(left: 13)) + : null, + child: Column( + crossAxisAlignment: isSelf + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + if ((isSelf && isShowNickNameForSelf) || + (!isSelf && isShowNickNameForOthers)) + widget.topRowBuilder != null + ? widget.topRowBuilder!(context, message) + : Container( + margin: const EdgeInsets.only(bottom: 4), + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context) + .size + .width / + 1.7), + child: Text( + MessageUtils.getDisplayName(message), + overflow: TextOverflow.ellipsis, + style: widget.themeData + ?.nickNameTextStyle ?? + TextStyle( + fontSize: 12, + color: theme.weakTextColor), + ), + )), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (isSelf) + renderHoverTipAndReadStatus(model, isSelf, + message, isPeerRead, theme), + Container( + constraints: BoxConstraints( + maxWidth: constraints.maxWidth * 0.77, + ), + child: Builder(builder: (context) { + return Column( + crossAxisAlignment: + (message.isSelf ?? true) + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + GestureDetector( + child: IgnorePointer( + ignoring: model.isMultiSelect, + child: _getMessageItemBuilder( + message, + message.status, + model)), + onSecondaryTapDown: (details) { + if (widget.onLongPress != null) { + widget.onLongPress!( + context, message); + return; + } + if (!PlatformUtils().isMobile) { + if (widget.allowLongPress) { + _onOpenToolTip( + context, + message, + model, + theme, + details, + false, + false); + } + } + }, + onLongPress: () { + if (widget.onLongPress != null) { + widget.onLongPress!( + context, message); + return; + } + if (widget.allowLongPress && + PlatformUtils().isMobile) { + _onOpenToolTip( + context, + message, + model, + theme, + null, + false, + false); + } + }, + onTapDown: (details) { + _tapDetails = details; + }, + ), + TIMUIKitTextTranslationElem( + message: message, + isUseDefaultEmoji: + widget.isUseDefaultEmoji, + customEmojiStickerList: + widget.customEmojiStickerList, + isFromSelf: message.isSelf ?? true, + isShowJump: false, + clearJump: () {}, + chatModel: model) + ], + ); + }), + ), + if (!isSelf && + message.elemType == + MessageElemType.V2TIM_ELEM_TYPE_SOUND && + message.localCustomInt != null && + message.localCustomInt != + HistoryMessageDartConstant.read) + Padding( + padding: const EdgeInsets.only( + left: 5, bottom: 12), + child: Icon(Icons.circle, + color: theme.cautionColor, size: 10)), + if (!isSelf) + renderHoverTipAndReadStatus(model, isSelf, + message, isPeerRead, theme), + ], ), - ], + if (widget.bottomRowBuilder != null) + widget.bottomRowBuilder!(context, message) + ], + ), + ), + if (widget.message.elemType == 6 && isDownloadWaiting) + Container( + margin: const EdgeInsets.only(top: 24, left: 6), + child: LoadingAnimationWidget.threeArchedCircle( + color: theme.weakTextColor ?? Colors.grey, + size: 20, + ), + ), + if (isSelf && widget.showAvatar) + widget.userAvatarBuilder != null + ? widget.userAvatarBuilder!(context, message) + : SizedBox( + width: 40, + height: 40, + child: InkWell( + onTapDown: (details) { + if (widget.onTapForOthersPortrait != null && + widget.allowAvatarTap) { + widget.onTapForOthersPortrait!( + message.sender ?? "", details); + } + }, + child: Avatar( + faceUrl: message.faceUrl ?? "", + showName: + MessageUtils.getDisplayName(message)), + ), + ), + ], + ), ), ), ), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_message_tooltip.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_message_tooltip.dart index 00bc57d..d7f6016 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_message_tooltip.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_message_tooltip.dart @@ -1,11 +1,15 @@ // ignore_for_file: non_constant_identifier_names, avoid_print +import 'dart:convert'; +import 'dart:io'; import 'dart:math'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; @@ -13,11 +17,11 @@ import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; - import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/forward_message_screen.dart'; - -import '../TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart'; +import 'package:tencent_open_file/tencent_open_file.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:path/path.dart' as path; class TIMUIKitMessageTooltip extends StatefulWidget { /// tool tips panel configuration, long press message will show tool tips panel @@ -46,6 +50,8 @@ class TIMUIKitMessageTooltip extends StatefulWidget { final TUIChatSeparateViewModel model; + final bool isShowMoreSticker; + const TIMUIKitMessageTooltip( {Key? key, this.toolTipsConfig, @@ -56,7 +62,8 @@ class TIMUIKitMessageTooltip extends StatefulWidget { this.onLongPressForOthersHeadPortrait, required this.selectEmojiPanelPosition, required this.onCloseTooltip, - required this.onSelectSticker}) + required this.onSelectSticker, + this.isShowMoreSticker = false}) : super(key: key); @override @@ -65,7 +72,52 @@ class TIMUIKitMessageTooltip extends StatefulWidget { class TIMUIKitMessageTooltipState extends TIMUIKitState { + final TUIChatGlobalModel globalModal = serviceLocator(); bool isShowMoreSticker = false; + bool isShowOpenFile = false; + String filePath = ""; + + @override + void initState() { + super.initState(); + hasFile(); + isShowMoreSticker = widget.isShowMoreSticker; + } + + hasFile() { + if (PlatformUtils().isMobile || widget.message.fileElem == null) { + isShowOpenFile = false; + return; + } + if (PlatformUtils().isWeb) { + isShowOpenFile = true; + return; + } + if (PlatformUtils().isDesktop) { + if (globalModal.getMessageProgress(widget.message.msgID) == 100) { + String savePath = + TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? + globalModal.getFileMessageLocation(widget.message.msgID); + File f = File(savePath); + if (f.existsSync() && widget.message.msgID != null) { + filePath = savePath; + isShowOpenFile = true; + return; + } + isShowOpenFile = false; + return; + } + String savePath = widget.message.fileElem!.localUrl ?? ''; + File f = File(savePath); + if (f.existsSync() && widget.message.msgID != null) { + filePath = savePath; + globalModal.setMessageProgress(widget.message.msgID!, 100); + isShowOpenFile = true; + return; + } + } + isShowOpenFile = false; + } bool isRevocable(int timestamp, int upperTimeLimit) => (DateTime.now().millisecondsSinceEpoch / 1000).ceil() - timestamp < @@ -73,10 +125,10 @@ class TIMUIKitMessageTooltipState Widget ItemInkWell({ Widget? child, - GestureTapCallback? onTap + GestureTapCallback? onTap, }) { return SizedBox( - width: 40, + width: 44, child: InkWell( onTap: onTap, splashColor: Colors.white, @@ -88,69 +140,105 @@ class TIMUIKitMessageTooltipState ); } - _buildLongPressTipItem(TUITheme theme, TUIChatSeparateViewModel model) { + bool isVoteMessage(V2TimMessage message) { + bool isvote = false; + V2TimCustomElem? custom = message.customElem; + + if (custom != null) { + String? data = custom.data; + if (data != null && data.isNotEmpty) { + try { + Map mapData = json.decode(data); + if (mapData["businessID"] == "group_poll") { + isvote = true; + } + } catch (err) { + // err + } + } + } + return isvote; + } + + _buildLongPressTipItem( + TUITheme theme, TUIChatSeparateViewModel model, V2TimMessage message) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final isCanRevoke = isRevocable( widget.message.timestamp!, model.chatConfig.upperRecallTime); final shouldShowRevokeAction = isCanRevoke && - (widget.message.isSelf ?? false) && + (widget.message.isSelf ?? true) && widget.message.status != MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL; final shouldShowReplyAction = !(widget.message.customElem?.data != null && MessageUtils.isCallingData(widget.message.customElem!.data!)); final shouldShowForwardAction = !(widget.message.customElem?.data != null && MessageUtils.isCallingData(widget.message.customElem!.data!)); final tooltipsConfig = widget.toolTipsConfig; - final defaultTipsList = [ - { - "label": TIM_t("复制"), - "id": "copyMessage", - "icon": "images/copy_message.png" - }, - if(shouldShowForwardAction) - { - "label": TIM_t("转发"), - "id": "forwardMessage", - "icon": "images/forward_message.png" - }, - { - "label": TIM_t("多选"), - "id": "multiSelect", - "icon": "images/multi_message.png" - }, + final List defaultTipsList = [ + if (isShowOpenFile) + MessageToolTipItem( + label: TIM_t("打开"), + id: "open", + iconImageAsset: "images/open_in_new.png", + onClick: () => _onTap("open", model)), + if (isShowOpenFile && PlatformUtils().isDesktop) + MessageToolTipItem( + label: PlatformUtils().isMacOS ? TIM_t("在访达中打开") : TIM_t("查看文件夹"), + id: "finder", + iconImageAsset: "images/folder_open.png", + onClick: () => _onTap("finder", model)), + MessageToolTipItem( + label: TIM_t("复制"), + id: "copyMessage", + iconImageAsset: "images/copy_message.png", + onClick: () => _onTap("copyMessage", model)), + if (shouldShowForwardAction && !isVoteMessage(widget.message)) + MessageToolTipItem( + label: TIM_t("转发"), + id: "forwardMessage", + iconImageAsset: "images/forward_message.png", + onClick: () => _onTap("forwardMessage", model)), + MessageToolTipItem( + label: TIM_t("多选"), + id: "multiSelect", + iconImageAsset: "images/multi_message.png", + onClick: () => _onTap("multiSelect", model)), if (shouldShowReplyAction) - { - "label": TIM_t("引用"), - "id": "replyMessage", - "icon": "images/reply_message.png" - }, - { - "label": TIM_t("删除"), - "id": "delete", - "icon": "images/delete_message.png" - }, - { - "label": TIM_t("翻译"), - "id": "translate", - "icon": "images/translate.png" - }, + MessageToolTipItem( + label: TIM_t(model.chatConfig.isAtWhenReply ? "回复" : "引用"), + id: "replyMessage", + iconImageAsset: "images/reply_message.png", + onClick: () => _onTap("replyMessage", model)), + MessageToolTipItem( + label: TIM_t("删除"), + id: "delete", + iconImageAsset: "images/delete_message.png", + onClick: () => _onTap("delete", model)), + MessageToolTipItem( + label: TIM_t("翻译"), + id: "translate", + iconImageAsset: "images/translate.png", + onClick: () => _onTap("translate", model)), if (shouldShowRevokeAction) - { - "label": TIM_t("撤回"), - "id": "revoke", - "icon": "images/revoke_message.png" - } + MessageToolTipItem( + label: TIM_t("撤回"), + id: "revoke", + iconImageAsset: "images/revoke_message.png", + onClick: () => _onTap("revoke", model)), ]; - List formatedTipsList = defaultTipsList; + List defaultFormattedTipsList = defaultTipsList; if (tooltipsConfig != null) { - formatedTipsList = defaultTipsList.where((element) { - final type = element["id"]; + defaultFormattedTipsList = defaultTipsList.where((element) { + final type = element.id; if (type == "copyMessage") { - return tooltipsConfig.showCopyMessage && widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT; + return tooltipsConfig.showCopyMessage && + widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT; } if (type == "forwardMessage") { - return tooltipsConfig.showForwardMessage; + return tooltipsConfig.showForwardMessage && !isDesktopScreen; } if (type == "replyMessage") { - return tooltipsConfig.showReplyMessage; + return tooltipsConfig.showReplyMessage && !isDesktopScreen; } if (type == "delete") { return (!PlatformUtils().isWeb) && tooltipsConfig.showDeleteMessage; @@ -158,67 +246,158 @@ class TIMUIKitMessageTooltipState if (type == "multiSelect") { return tooltipsConfig.showMultipleChoiceMessage; } - if (type == "translate") { - return tooltipsConfig.showTranslation && widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT; - } + if (type == "revoke") { return tooltipsConfig.showRecallMessage; } + if (type == "translate") { + return tooltipsConfig.showTranslation && + widget.message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT; + } return true; }).toList(); } - return formatedTipsList - .map( - (item) => Material( - color: Colors.white, - child: ItemInkWell( - onTap: () { - _onTap(item["id"]!, model); - }, - child: Column( - children: [ - Image.asset( - item["icon"]!, - package: 'tencent_cloud_chat_uikit', - width: 20, - height: 20, + + final List? customList = + widget.toolTipsConfig?.additionalMessageToolTips != null + ? (widget.toolTipsConfig?.additionalMessageToolTips!( + message, widget.onCloseTooltip)) + : []; + + List formattedTipsList = [ + ...defaultFormattedTipsList, + ...?customList, + ]; + + List widgetList = []; + if (isDesktopScreen) { + widgetList = formattedTipsList + .map( + (item) => Material( + color: Colors.white, + child: InkWell( + onTap: () { + item.onClick(); + }, + child: Container( + padding: const EdgeInsets.all(6), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset( + item.iconImageAsset, + package: 'tencent_cloud_chat_uikit', + width: 20, + height: 20, + ), + const SizedBox( + height: 4, + width: 8, + ), + Text( + item.label, + style: TextStyle( + decoration: TextDecoration.none, + color: theme.darkTextColor, + fontSize: 12, + ), + ) + ], ), - const SizedBox( - height: 4, - ), - Text( - item["label"]!, - style: TextStyle( - decoration: TextDecoration.none, - color: theme.darkTextColor, - fontSize: 10, - ), - ) - ], + ), ), ), - ), - ) - .toList(); + ) + .toList(); + } else { + widgetList = formattedTipsList + .map( + (item) => Material( + color: Colors.white, + child: ItemInkWell( + onTap: () { + item.onClick(); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + item.iconImageAsset, + package: 'tencent_cloud_chat_uikit', + width: 20, + height: 20, + ), + const SizedBox( + height: 4, + width: 60, + ), + Text( + item.label, + style: TextStyle( + decoration: TextDecoration.none, + color: theme.darkTextColor, + fontSize: 10, + ), + ) + ], + ), + ), + ), + ) + .toList(); + } + if (widgetList.isEmpty && widget.isUseMessageReaction == false) { + widget.onCloseTooltip(); + } + + return widgetList; } _onTap(String operation, TUIChatSeparateViewModel model) async { final messageItem = widget.message; final msgID = messageItem.msgID as String; switch (operation) { + case "open": + if (PlatformUtils().isDesktop) { + final String savePath = + TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? + globalModal.getFileMessageLocation(widget.message.msgID); + launchUrl(Uri.file(savePath)); + } else { + if (PlatformUtils().isWindows) { + OpenFile.open(widget.message.fileElem?.path ?? ""); + } else { + launchUrl( + Uri.parse(widget.message.fileElem?.path ?? ""), + mode: LaunchMode.externalApplication, + ); + } + } + break; + case "finder": + final String savePath = + TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? + globalModal.getFileMessageLocation(widget.message.msgID); + final String fileDir = path.dirname(savePath); + if (PlatformUtils().isWindows) { + OpenFile.open(fileDir); + } else { + launchUrl(Uri.file(fileDir)); + } + break; case "delete": model.deleteMsg(msgID, webMessageInstance: messageItem.messageFromWeb); break; case "revoke": model.revokeMsg(msgID, messageItem.messageFromWeb); break; + case 'translate': + model.translateText(widget.message); + break; case "multiSelect": model.updateMultiSelectStatus(true); model.addToMultiSelectedMessageList(widget.message); break; - case 'translate': - model.translateText(widget.message); - break; case "forwardMessage": model.addToMultiSelectedMessageList(widget.message); Navigator.push( @@ -238,16 +417,15 @@ class TIMUIKitMessageTooltipState type: TIMCallbackType.INFO, infoRecommendText: TIM_t("已复制"), infoCode: 6660408)); - } catch (e) { - print(e); - } + // ignore: empty_catches + } catch (e) {} } break; case "replyMessage": model.repliedMessage = widget.message; if (widget.allowAtUserWhenReply && widget.onLongPressForOthersHeadPortrait != null && - !(widget.message.isSelf ?? false)) { + !(widget.message.isSelf ?? true)) { widget.onLongPressForOthersHeadPortrait!( widget.message.sender, widget.message.nickName); } @@ -264,7 +442,8 @@ class TIMUIKitMessageTooltipState @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return MultiProvider( providers: [ ChangeNotifierProvider.value(value: widget.model), @@ -278,16 +457,38 @@ class TIMUIKitMessageTooltipState ? widget.toolTipsConfig!.additionalItemBuilder!( widget.message, widget.onCloseTooltip, null, context) : null; + final message = widget.message; return Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: isDesktopScreen + ? BoxDecoration( + boxShadow: const [ + BoxShadow( + color: Color(0xCCbebebe), + offset: Offset(2, 2), + blurRadius: 10, + spreadRadius: 1, + ), + ], + border: Border.all( + width: 1, + color: hexToColor("dee0e3"), + ), + color: Colors.white, + borderRadius: const BorderRadius.all(Radius.circular(10)), + ) + : null, + color: isDesktopScreen ? null : Colors.white, + padding: EdgeInsets.symmetric( + horizontal: 8, vertical: isDesktopScreen ? 8 : 4), child: ConstrainedBox( constraints: BoxConstraints( - maxWidth: min(MediaQuery.of(context).size.width * 0.7, 350), + maxWidth: min(MediaQuery.of(context).size.width * 0.75, 350), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ - if (widget.isUseMessageReaction && + if ((!isDesktopScreen || widget.isShowMoreSticker) && + widget.isUseMessageReaction && widget.selectEmojiPanelPosition == SelectEmojiPanelPosition.up) TIMUIKitMessageReactionEmojiSelectPanel( @@ -299,7 +500,8 @@ class TIMUIKitMessageTooltipState }); }, ), - if (widget.isUseMessageReaction && + if (!isDesktopScreen && + widget.isUseMessageReaction && widget.selectEmojiPanelPosition == SelectEmojiPanelPosition.up && isShowMoreSticker == false) @@ -314,40 +516,58 @@ class TIMUIKitMessageTooltipState Row( mainAxisSize: MainAxisSize.min, children: [ - if (widget.isUseMessageReaction) + if (!isDesktopScreen && widget.isUseMessageReaction) Expanded( child: Wrap( direction: Axis.horizontal, - alignment: ScreenUtils.getFormFactor(context) == - ScreenType.Handset - ? WrapAlignment.spaceBetween - : WrapAlignment.start, + alignment: + TUIKitScreenUtils.getFormFactor(context) == + DeviceType.Mobile + ? WrapAlignment.spaceBetween + : WrapAlignment.start, spacing: 4, runSpacing: 8, children: [ - ..._buildLongPressTipItem(theme, model), + ..._buildLongPressTipItem(theme, model, message), if (extraTipsActionItem != null) extraTipsActionItem ], )), - if (!widget.isUseMessageReaction) - Wrap( - direction: Axis.horizontal, - alignment: ScreenUtils.getFormFactor(context) == - ScreenType.Handset - ? WrapAlignment.spaceAround - : WrapAlignment.start, - spacing: 4, - runSpacing: 16, - children: [ - ..._buildLongPressTipItem(theme, model), - if (extraTipsActionItem != null) - extraTipsActionItem - ], - ) + if (!isDesktopScreen && !widget.isUseMessageReaction) + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: min( + MediaQuery.of(context).size.width * 0.75, + 350), + ), + child: Wrap( + direction: Axis.horizontal, + alignment: + TUIKitScreenUtils.getFormFactor(context) == + DeviceType.Mobile + ? WrapAlignment.spaceBetween + : WrapAlignment.start, + spacing: 4, + runSpacing: 8, + children: [ + ..._buildLongPressTipItem( + theme, model, message), + if (extraTipsActionItem != null) + extraTipsActionItem + ], + ), + ), + if (isDesktopScreen) + Table(columnWidths: const { + 0: IntrinsicColumnWidth(), + }, children: [ + ..._buildLongPressTipItem(theme, model, message) + .map((e) => TableRow(children: [e])) + ]) ], ), - if (widget.isUseMessageReaction && + if (!isDesktopScreen && + widget.isUseMessageReaction && widget.selectEmojiPanelPosition == SelectEmojiPanelPosition.down && isShowMoreSticker == false) @@ -358,7 +578,8 @@ class TIMUIKitMessageTooltipState indent: 0, // endIndent: 10, color: Colors.black12)), - if (widget.isUseMessageReaction && + if ((!isDesktopScreen || widget.isShowMoreSticker) && + widget.isUseMessageReaction && widget.selectEmojiPanelPosition == SelectEmojiPanelPosition.down) TIMUIKitMessageReactionEmojiSelectPanel( diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart index 838b933..6ed275f 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use_from_same_package + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -33,6 +35,9 @@ class TIMUIKitHistoryMessageListContainer extends StatefulWidget { /// message item builder, works for customize all message types and row layout. final MessageItemBuilder? messageItemBuilder; + /// The controller for text field. + final TIMUIKitInputTextFieldController? textFieldController; + /// the builder for avatar final Widget Function(BuildContext context, V2TimMessage message)? userAvatarBuilder; @@ -46,7 +51,7 @@ class TIMUIKitHistoryMessageListContainer extends StatefulWidget { /// conversation type final ConvType conversationType; - final void Function(String userID)? onTapAvatar; + final void Function(String userID, TapDownDetails tapDetails)? onTapAvatar; @Deprecated( "Nickname will not show in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead") @@ -62,9 +67,6 @@ class TIMUIKitHistoryMessageListContainer extends StatefulWidget { final List customEmojiStickerList; - /// The controller for text field. - final TIMUIKitInputTextFieldController? textFieldController; - final bool isAllowScroll; final V2TimConversation conversation; @@ -105,12 +107,13 @@ class _TIMUIKitHistoryMessageListContainerState List historyMessageList = []; - Future requestForData(String? lastMsgID, LoadDirection direction, TUIChatSeparateViewModel model, + Future requestForData(String? lastMsgID, LoadDirection direction, + TUIChatSeparateViewModel model, [int? count]) async { - print("requestForData $lastMsgID $direction"); - if ((direction == LoadDirection.previous && model.haveMoreData) || (direction == LoadDirection.latest && model.haveMoreLatestData)) { - await model.loadData( - direction: direction, + if ((direction == LoadDirection.previous && model.haveMoreData) || + (direction == LoadDirection.latest && model.haveMoreLatestData)) { + await model.loadChatRecord( + direction: direction, count: count ?? (kIsWeb ? 15 : HistoryMessageDartConstant.getCount), lastMsgID: lastMsgID); } @@ -152,6 +155,7 @@ class _TIMUIKitHistoryMessageListContainerState mainHistoryListConfig: widget.mainHistoryListConfig, itemBuilder: (context, message) { return TIMUIKitHistoryMessageListItem( + textFieldController: widget.textFieldController, userAvatarBuilder: widget.userAvatarBuilder, customEmojiStickerList: widget.customEmojiStickerList, isUseDefaultEmoji: widget.isUseDefaultEmoji, @@ -166,7 +170,6 @@ class _TIMUIKitHistoryMessageListContainerState message: message!, showAvatar: chatConfig.isShowAvatar, onTapForOthersPortrait: widget.onTapAvatar, - textFieldController: widget.textFieldController, messageItemBuilder: widget.messageItemBuilder, onLongPressForOthersHeadPortrait: widget.onLongPressForOthersHeadPortrait, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_message_read_receipt.dart b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_message_read_receipt.dart index 5c9a738..2b1c04a 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_message_read_receipt.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_message_read_receipt.dart @@ -3,13 +3,16 @@ import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/message_read_receipt.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; class TIMUIKitMessageReadReceipt extends TIMUIKitStatelessWidget { final V2TimMessage messageItem; - final void Function(String)? onTapAvatar; + final void Function(String, TapDownDetails tapDetails)? onTapAvatar; TIMUIKitMessageReadReceipt( {Key? key, this.onTapAvatar, required this.messageItem}) @@ -20,31 +23,48 @@ class TIMUIKitMessageReadReceipt extends TIMUIKitStatelessWidget { final TUITheme theme = value.theme; final TUIChatSeparateViewModel model = Provider.of(context, listen: false); + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Selector( builder: (context, value, child) { - if (value == null || value.unreadCount == 0 && value.readCount == 0) { - return Container(); - } + // if (value == null || value.unreadCount == 0 && value.readCount == 0) { + // return Container(); + // } return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { - if ((value.readCount ?? 0) > 0) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => MessageReadReceipt( - model: model, - onTapAvatar: onTapAvatar, - messageItem: messageItem, - unreadCount: value.unreadCount ?? 0, - readCount: value.readCount ?? 0))); + if ((value?.readCount ?? 0) > 0) { + if(isDesktopScreen){ + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.messageReadDetails, + context: context, + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.8, + title: TIM_t("消息详情"), + child: (onClose) => MessageReadReceipt( + model: model, + onTapAvatar: onTapAvatar, + messageItem: messageItem, + unreadCount: value?.unreadCount ?? 0, + readCount: value?.readCount ?? 0) + ); + }else{ + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MessageReadReceipt( + model: model, + onTapAvatar: onTapAvatar, + messageItem: messageItem, + unreadCount: value?.unreadCount ?? 0, + readCount: value?.readCount ?? 0))); + } } }, child: Container( - padding: - const EdgeInsets.only(bottom: 3, right: 6, left: 6, top: 6), - child: (value.unreadCount == 0 && (value.readCount ?? 0) > 0) + padding: EdgeInsets.only( + bottom: 3, right: 6, left: 6, top: isDesktopScreen ? 2 : 6), + child: ((value?.unreadCount ?? 0) == 0 && (value?.readCount ?? 0) > 0) ? Icon( Icons.check_circle_outline, size: 18, @@ -58,12 +78,12 @@ class TIMUIKitMessageReadReceipt extends TIMUIKitStatelessWidget { shape: BoxShape.circle, border: Border.all( width: 1.3, - color: (value.readCount ?? 0) > 0 + color: (value?.readCount ?? 0) > 0 ? theme.primaryColor! : theme.weakTextColor!)), - child: (value.readCount ?? 0) > 0 + child: (value?.readCount ?? 0) > 0 ? Text( - '${value.readCount}', + '${value?.readCount ?? 0}', textAlign: TextAlign.center, style: TextStyle( fontSize: 8, color: theme.primaryColor), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar.dart index 6690568..396a60b 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar.dart @@ -9,6 +9,7 @@ import 'package:tencent_cloud_chat_uikit/data_services/friendShip/friendship_ser import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.dart'; import 'package:tuple/tuple.dart'; @@ -30,7 +31,9 @@ class TIMUIKitAppBar extends StatefulWidget implements PreferredSizeWidget { /// If allow update the conversation show name automatically. final bool isConversationShowNameFixed; - final bool showC2cMessageEditStaus; + final bool showC2cMessageEditStatus; + + final GestureTapDownCallback? onClickTitle; const TIMUIKitAppBar({ Key? key, @@ -39,7 +42,8 @@ class TIMUIKitAppBar extends StatefulWidget implements PreferredSizeWidget { this.showTotalUnReadCount = true, this.conversationID = "", this.conversationShowName = "", - this.showC2cMessageEditStaus = true, + this.showC2cMessageEditStatus = true, + this.onClickTitle, }) : super(key: key); @override @@ -76,9 +80,8 @@ class _TIMUIKitAppBarState extends TIMUIKitState { changedInfo.userProfile?.userID) ?? ""; } + // ignore: empty_catches } catch (e) { - // ignore: avoid_print - print(e); } }, ); @@ -100,9 +103,8 @@ class _TIMUIKitAppBarState extends TIMUIKitState { setState(() {}); } } + // ignore: empty_catches } catch (e) { - // ignore: avoid_print - print(e); } }, ); @@ -159,9 +161,8 @@ class _TIMUIKitAppBarState extends TIMUIKitState { ""; }); } + // ignore: empty_catches } catch (e) { - // ignore: avoid_print - print(e); } } @@ -172,11 +173,16 @@ class _TIMUIKitAppBarState extends TIMUIKitState { final setAppbar = widget.config; final TUIChatSeparateViewModel chatVM = Provider.of(context); + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return AppBar( - backgroundColor: setAppbar?.backgroundColor ?? theme.chatHeaderBgColor, + backgroundColor: setAppbar?.backgroundColor ?? + theme.chatHeaderBgColor ?? + theme.appbarBgColor ?? + theme.primaryColor, actionsIconTheme: setAppbar?.actionsIconTheme, foregroundColor: setAppbar?.foregroundColor, - elevation: setAppbar?.elevation, + elevation: setAppbar?.elevation ?? (isDesktopScreen ? 0 : 1), bottom: setAppbar?.bottom, bottomOpacity: setAppbar?.bottomOpacity ?? 1.0, titleSpacing: setAppbar?.titleSpacing, @@ -188,46 +194,28 @@ class _TIMUIKitAppBarState extends TIMUIKitState { toolbarOpacity: setAppbar?.toolbarOpacity ?? 1.0, toolbarTextStyle: setAppbar?.toolbarTextStyle, textTheme: setAppbar?.textTheme, - flexibleSpace: setAppbar?.backgroundColor == null - ? theme.chatHeaderBgColor != null - ? setAppbar?.flexibleSpace ?? - Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? - CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ) - : null - : null, iconTheme: setAppbar?.iconTheme ?? const IconThemeData( color: Colors.white, ), - // title: setAppbar?.title ?? - // Text( - // _conversationShowName, - // style: const TextStyle( - // color: Colors.white, - // fontSize: 17, - // ), - // ), title: TIMUIKitAppBarTitle( title: setAppbar?.title, - textStyle: setAppbar?.textTheme?.titleMedium, + onClick: widget.onClickTitle, + textStyle: setAppbar?.textTheme?.titleMedium ?? + TextStyle( + color: theme.appbarTextColor ?? hexToColor("010000"), + fontSize: 16), conversationShowName: _conversationShowName, - showC2cMessageEditStaus: widget.showC2cMessageEditStaus, + showC2cMessageEditStatus: widget.showC2cMessageEditStatus, fromUser: widget.conversationID, ), - centerTitle: setAppbar?.centerTitle ?? true, - leadingWidth: setAppbar?.leadingWidth ?? 70, + centerTitle: setAppbar?.centerTitle ?? (isDesktopScreen ? false : true), + leadingWidth: setAppbar?.leadingWidth ?? (isDesktopScreen ? 8 : 70), leading: Selector>( builder: (context, data, _) { final isMultiSelect = data.item1; final unReadCount = data.item2; - return isMultiSelect + return (!isDesktopScreen && isMultiSelect) ? TextButton( onPressed: () { chatVM.updateMultiSelectStatus(false); @@ -235,42 +223,49 @@ class _TIMUIKitAppBarState extends TIMUIKitState { child: Text( TIM_t('取消'), style: setAppbar?.textTheme?.titleMedium ?? - const TextStyle( - color: Colors.white, + TextStyle( + color: + theme.appbarTextColor ?? hexToColor("010000"), fontSize: 16, ), ), ) : setAppbar?.leading ?? - Row( - children: [ - IconButton( - padding: const EdgeInsets.only(left: 16), - constraints: const BoxConstraints(), - icon: Icon( - Icons.arrow_back_ios, - color: setAppbar?.textTheme?.titleMedium?.color ?? - Colors.white, - size: 17, - ), - onPressed: () async { - chatVM.repliedMessage = null; - Navigator.pop(context); - }, - ), - if (widget.showTotalUnReadCount && unReadCount > 0) - Container( - width: 22, - height: 22, - alignment: Alignment.center, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: theme.cautionColor, - ), - child: Text(_getTotalUnReadCount(unReadCount)), - ), - ], - ); + (isDesktopScreen + ? Container() + : Row( + children: [ + IconButton( + padding: const EdgeInsets.only(left: 16), + constraints: const BoxConstraints(), + icon: Icon( + Icons.arrow_back_ios, + color: setAppbar + ?.textTheme?.titleMedium?.color ?? + theme.appbarTextColor ?? + hexToColor("010000"), + size: 17, + ), + onPressed: () async { + chatVM.repliedMessage = null; + Navigator.pop(context); + }, + ), + if (widget.showTotalUnReadCount && + unReadCount > 0) + Container( + width: 22, + height: 22, + alignment: Alignment.center, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: theme.cautionColor, + ), + child: + Text(_getTotalUnReadCount(unReadCount)), + ), + ], + )); }, shouldRebuild: (prev, next) => prev.item1 != next.item1 || prev.item2 != next.item2, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.dart index 08b8450..92126d2 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title.dart @@ -6,8 +6,9 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_glo class TIMUIKitAppBarTitle extends StatelessWidget { final Widget? title; final String conversationShowName; - final bool showC2cMessageEditStaus; + final bool showC2cMessageEditStatus; final String fromUser; + final GestureTapDownCallback? onClick; final TextStyle? textStyle; const TIMUIKitAppBarTitle( @@ -15,10 +16,24 @@ class TIMUIKitAppBarTitle extends StatelessWidget { this.title, this.textStyle, required this.conversationShowName, - required this.showC2cMessageEditStaus, - required this.fromUser}) + required this.showC2cMessageEditStatus, + required this.fromUser, this.onClick}) : super(key: key); + Widget titleText(String text){ + return InkWell( + onTapDown: onClick, + child: Text( + text, + style: textStyle ?? + const TextStyle( + color: Colors.white, + fontSize: 17, + ), + ), + ); + } + // String conversationShowName; @override Widget build(BuildContext context) { @@ -28,36 +43,19 @@ class TIMUIKitAppBarTitle extends StatelessWidget { if (title != null) { return title!; } - return Text( - conversationShowName, - style: textStyle ?? - const TextStyle( - color: Colors.white, - fontSize: 17, - ), - ); + return titleText(conversationShowName,); } else { - if (showC2cMessageEditStaus) { - return Text( - TIM_t("对方正在输入中..."), - style: textStyle ?? - const TextStyle( - color: Colors.white, - fontSize: 17, - ), - ); + if (showC2cMessageEditStatus) { + return titleText( + TIM_t("对方正在输入中..."),); + } else { if (title != null) { return title!; } - return Text( - conversationShowName, - style: textStyle ?? - const TextStyle( - color: Colors.white, - fontSize: 17, - ), - ); + return titleText( + conversationShowName,); + } } } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_detail.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_detail.dart index 4b73b59..d69f4b5 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_detail.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_detail.dart @@ -20,7 +20,7 @@ class TIMUIKitMessageReactionDetail extends StatefulWidget { /// the sticker list from message reaction final List stickerList; - final Function(String userID)? onTapAvatar; + final Function(String userID, TapDownDetails tapDetails)? onTapAvatar; const TIMUIKitMessageReactionDetail( {required this.currentStickerIndex, @@ -42,7 +42,7 @@ class TIMUIKitMessageReactionDetailState serviceLocator(); Widget getUserItem( - String userID, TUITheme theme, Function(String userID)? onTapAvatar) { + String userID, TUITheme theme, Function(String userID, TapDownDetails tapDetails)? onTapAvatar) { V2TimGroupMemberFullInfo? memberInfo; String showName = userID; try { @@ -66,11 +66,11 @@ class TIMUIKitMessageReactionDetailState // e } - return GestureDetector( - onTap: () { + return InkWell( + onTapDown: (tapDetails) { if (onTapAvatar != null) { if (userID != selfInfoModel.loginInfo?.userID) { - onTapAvatar(userID); + onTapAvatar(userID, tapDetails); } } }, @@ -137,7 +137,7 @@ class TIMUIKitMessageReactionDetailState } Widget getStickerNameList( - int sticker, TUITheme theme, Function(String userID)? onTapAvatar) { + int sticker, TUITheme theme, Function(String userID, TapDownDetails tapDetails)? onTapAvatar) { final nameList = widget.messageReaction[sticker.toString()]; return SingleChildScrollView( child: Column( diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart index 9adbd8b..323ee05 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/message_reaction_emoji.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart' as emoji; @@ -33,6 +34,7 @@ class TIMUIKitMessageReactionEmojiSelectPanelState _buildSimplePanel(TUITheme theme) { final List> emojiData = messageReactionEmojiData; + final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop; return Material( color: Colors.white, child: ExtendedWrap( @@ -41,7 +43,8 @@ class TIMUIKitMessageReactionEmojiSelectPanelState crossAxisAlignment: WrapCrossAlignment.center, runSpacing: 24, children: [ - GestureDetector( + if(!isDesktopScreen) + GestureDetector( onTap: () { widget.onClickShowMore(!widget.isShowMoreSticker); }, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_item.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_item.dart index 89ec53f..2506e71 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_item.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_item.dart @@ -78,7 +78,7 @@ class TIMUIKitMessageReactionShowItem extends TIMUIKitStatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ - GestureDetector( + InkWell( onTap: clickOnCurrentSticker, child: Container( margin: EdgeInsets.only( @@ -87,8 +87,8 @@ class TIMUIKitMessageReactionShowItem extends TIMUIKitStatelessWidget { child: Text( String.fromCharCode(sticker), style: TextStyle( - fontSize: (!PlatformUtils().isIOS) ? 12 : 16, - ), + fontSize: (!PlatformUtils().isIOS) ? 12 : 16, + color: hexToColor("f9453d")), ), ), ), @@ -145,11 +145,11 @@ class TIMUIKitMessageReactionShowItem extends TIMUIKitStatelessWidget { // e } } - return GestureDetector( - onTap: () { + return InkWell( + onTapDown: (tapDetails) { if (model.onTapAvatar != null) { if (e != selfInfoModel.loginInfo?.userID) { - model.onTapAvatar!(e); + model.onTapAvatar!(e, tapDetails); } } }, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_utils.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_utils.dart index ee82e42..041dc9f 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_utils.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_utils.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:tencent_im_base/tencent_im_base.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; @@ -16,8 +16,10 @@ class MessageReactionUtils { static CloudCustomData getCloudCustomData(V2TimMessage message) { CloudCustomData messageCloudCustomData; try { - messageCloudCustomData = - CloudCustomData.fromJson(json.decode(message.cloudCustomData!)); + messageCloudCustomData = CloudCustomData.fromJson(json.decode( + TencentUtils.checkString(message.cloudCustomData) != null + ? message.cloudCustomData! + : "{}")); } catch (e) { messageCloudCustomData = CloudCustomData(); } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart index da94359..3387b40 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; @@ -26,7 +27,7 @@ class TIMUIKitMessageReactionWrapper extends StatefulWidget { this.clearJump, required this.isFromSelf, this.backgroundColor, - required this.chatModel, + required this.chatModel, required this.message, this.borderRadius, required this.child, @@ -76,8 +77,10 @@ class _TIMUIKitMessageReactionWrapperState Map messageReaction = {}; CloudCustomData messageCloudCustomData; try { - messageCloudCustomData = CloudCustomData.fromJson( - json.decode(widget.message.cloudCustomData!)); + messageCloudCustomData = CloudCustomData.fromJson(json.decode( + TencentUtils.checkString(widget.message.cloudCustomData) != null + ? widget.message.cloudCustomData! + : "{}")); } catch (e) { messageCloudCustomData = CloudCustomData(); } @@ -134,7 +137,7 @@ class _TIMUIKitMessageReactionWrapperState } else { if ((widget.chatModel.jumpMsgID == widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? false)) { - if (widget.clearJump != null) { + if(widget.clearJump != null){ widget.clearJump!(); } } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart index fed5487..fd10412 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; @@ -28,10 +29,6 @@ class TIMUIKitFaceElem extends StatefulWidget { } class _TIMUIKitTextElemState extends TIMUIKitState { - @override - void initState() { - super.initState(); - } bool isFromNetwork() { return widget.path.startsWith('http'); @@ -51,8 +48,9 @@ class _TIMUIKitTextElemState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return TIMUIKitMessageReactionWrapper( - chatModel: widget.model, + chatModel: widget.model, isShowJump: widget.isShowJump, isFromSelf: widget.message.isSelf ?? true, clearJump: widget.clearJump, @@ -61,7 +59,7 @@ class _TIMUIKitTextElemState extends TIMUIKitState { child: Container( padding: const EdgeInsets.all(10), constraints: - BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.3), + BoxConstraints(maxWidth: MediaQuery.of(context).size.width * (isDesktopScreen ? 0.1 : 0.3)), child: isFromNetwork() ? Image.network(widget.path) : Image.asset(createPathFromNative(widget.path)), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart index 19b8474..f121465 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem.dart @@ -3,17 +3,18 @@ import 'dart:io'; import 'dart:math'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; import 'package:tencent_open_file/tencent_open_file.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; -import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; + import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_icon.dart'; @@ -75,23 +76,20 @@ class _TIMUIKitFileElemState extends TIMUIKitState { } if (model.getMessageProgress(widget.messageID) == 100) { - String savePath = widget.message.fileElem!.localUrl ?? + String savePath = TencentUtils.checkString(widget.message.fileElem!.localUrl) ?? model.getFileMessageLocation(widget.messageID); File f = File(savePath); if (f.existsSync() && widget.messageID != null) { filePath = savePath; - // model.setFileMessageLocation(widget.messageID!, filePath); return true; } return false; } - // String savePath = await getSavePath(); String savePath = widget.message.fileElem!.localUrl ?? ''; File f = File(savePath); if (f.existsSync() && widget.messageID != null) { filePath = savePath; model.setMessageProgress(widget.messageID!, 100); - // model.setFileMessageLocation(widget.messageID!, filePath); return true; } return false; @@ -110,8 +108,10 @@ class _TIMUIKitFileElemState extends TIMUIKitState { } addUrlToWaitingPath() async { - model.addWaitingList(widget.messageID!); - print("add path success"); + if(widget.messageID !=null ){ + model.addWaitingList(widget.messageID!); + print("add path success"); + } } checkIsWaiting() { @@ -127,22 +127,59 @@ class _TIMUIKitFileElemState extends TIMUIKitState { } downloadFile(TUITheme theme) async { - if (!await Permissions.checkPermission( - context, Permission.storage.value, theme)) { - return; + if(PlatformUtils().isMobile){ + if (PlatformUtils().isIOS) { + if (!await Permissions.checkPermission( + context, Permission.photosAddOnly.value, theme, false)) { + return; + } + } else { + final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; + if ((androidInfo.version.sdkInt ?? 0) >= 33) { + } else { + var storage = await Permissions.checkPermission( + context, Permission.storage.value, + ); + if(!storage){ + return; + } + } + } } await model.downloadFile(); } tryOpenFile(context, theme) async { - if (!await Permissions.checkPermission( - context, Permission.storage.value, theme)) { - return; + if(PlatformUtils().isMobile){ + if (PlatformUtils().isIOS) { + if (!await Permissions.checkPermission( + context, Permission.photosAddOnly.value, theme!, false)) { + return; + } + } else { + final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; + if ((androidInfo.version.sdkInt ?? 0) >= 33) { + } else { + var storage = await Permissions.checkPermission( + context, Permission.storage.value, + ); + if(!storage){ + return; + } + } + } } + try { - OpenFile.open(filePath); + if(PlatformUtils().isDesktop && !PlatformUtils().isWindows){ + launchUrl(Uri.file(filePath)); + }else{ + OpenFile.open(filePath); + } + // ignore: empty_catches } catch (e) { - print(e); } } @@ -181,7 +218,7 @@ class _TIMUIKitFileElemState extends TIMUIKitState { fileFormat = fileName.split(".")[max(fileName.split(".").length - 1, 0)]; } - return GestureDetector( + return InkWell( onTap: () async { if (PlatformUtils().isWeb) { launchUrl( diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_icon.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_icon.dart index ebf586a..e2853cb 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_icon.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_icon.dart @@ -7,8 +7,9 @@ import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget class TIMUIKitFileIcon extends TIMUIKitStatelessWidget { final String? fileFormat; + final double? size; - TIMUIKitFileIcon({this.fileFormat, Key? key}) : super(key: key); + TIMUIKitFileIcon( {this.size, this.fileFormat, Key? key}) : super(key: key); Map fileMap = { "doc": "images/word.png", @@ -34,6 +35,11 @@ class TIMUIKitFileIcon extends TIMUIKitStatelessWidget { "tif": "images/image_icon.png", "wmf": "images/image_icon.png", "dib": "images/image_icon.png", + "mp4": "images/video_icon.png", + "avi": "images/video_icon.png", + "mov": "images/video_icon.png", + "wmv": "images/video_icon.png", + "flv": "images/video_icon.png", }; Widget _getFileIcon() { @@ -46,8 +52,8 @@ class TIMUIKitFileIcon extends TIMUIKitStatelessWidget { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { return SizedBox( - height: 50, - width: 50, + height: size ?? 50, + width: size ?? 50, child: Container(padding: const EdgeInsets.all(4), child: _getFileIcon()), ); } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart index 0b44e04..2b1eed1 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem.dart @@ -3,24 +3,24 @@ import 'dart:async'; import 'dart:convert'; import 'package:crypto/crypto.dart'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:http/http.dart' as http; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_open_file/tencent_open_file.dart'; import 'package:universal_html/html.dart' as html; import 'dart:io'; import 'dart:math'; import 'dart:typed_data'; import 'package:cached_network_image/cached_network_image.dart'; - import 'package:flutter/material.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; - import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; - import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart'; @@ -31,6 +31,7 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageIt import 'package:tencent_cloud_chat_uikit/ui/widgets/image_screen.dart'; import 'package:transparent_image/transparent_image.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; +import 'package:url_launcher/url_launcher.dart'; class TIMUIKitImageElem extends StatefulWidget { final V2TimMessage message; @@ -79,10 +80,11 @@ class _TIMUIKitImageElem extends TIMUIKitState { decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(5)), border: Border.all( - width: 1, - color: theme?.black ?? Colors.white, + width: 2, + color: theme?.weakDividerColor ?? Colors.grey, )), - height: 100, + height: 170, + width: 170, child: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -135,9 +137,27 @@ class _TIMUIKitImageElem extends TIMUIKitState { return; } } else { - if (!await Permissions.checkPermission( - context, Permission.storage.value, theme!)) { - return; + final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; + if (PlatformUtils().isMobile) { + if ((androidInfo.version.sdkInt ?? 0) >= 33) { + final photos = await Permissions.checkPermission( + context, + Permission.photos.value, + theme, + ); + if (!photos) { + return; + } + } else { + final storage = await Permissions.checkPermission( + context, + Permission.storage.value, + ); + if (!storage) { + return; + } + } } } @@ -233,7 +253,8 @@ class _TIMUIKitImageElem extends TIMUIKitState { if (path != null && PlatformUtils().isWeb ? true : File(path!).existsSync()) { - return await _saveImageToLocal(context, path, isAsset: true, theme: theme); + return await _saveImageToLocal(context, path, + isAsset: true, theme: theme); } else { String imgUrl = getBigPicUrl(); if (widget.message.imageElem!.imageList![0]!.localUrl != '' && @@ -288,18 +309,22 @@ class _TIMUIKitImageElem extends TIMUIKitState { child: errorDisplay(context, theme), )); - Widget _renderLocalImage( - String imgPath, dynamic heroTag, double positionRadio, TUITheme? theme) { - double? currentPositionRadio; + Widget _renderLocalImage(String smallImage, dynamic heroTag, + double? positionRadio, TUITheme? theme, String? originImage) { + double? currentPositionRadio = positionRadio; + File imgF = File(smallImage); - File imgF = File(imgPath); bool isExist = imgF.existsSync(); - if (!isExist) { return errorDisplay(context, theme); } + Image image = Image.file(imgF); + String showImage = (originImage != null && File(originImage).existsSync()) + ? originImage + : smallImage; + image.image .resolve(const ImageConfiguration()) .addListener(ImageStreamListener((image, synchronousCall) { @@ -311,30 +336,42 @@ class _TIMUIKitImageElem extends TIMUIKitState { final preloadImage = model.preloadImageMap[ message.seq! + message.timestamp.toString() + (message.msgID ?? "")]; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + return Stack( alignment: AlignmentDirectional.topStart, children: [ - AspectRatio( - aspectRatio: currentPositionRadio ?? positionRadio, - child: Container( - decoration: const BoxDecoration(color: Colors.transparent), + if (!isDesktopScreen && currentPositionRadio != null) + AspectRatio( + aspectRatio: currentPositionRadio!, + child: Container( + decoration: const BoxDecoration(color: Colors.transparent), + ), ), - ), getImage( - GestureDetector( + InkWell( onTap: () { - Navigator.of(context).push( - PageRouteBuilder( - opaque: false, // set to false - pageBuilder: (_, __, ___) => ImageScreen( - imageProvider: FileImage(File(imgPath)), - heroTag: heroTag, - messageID: widget.message.msgID, - downloadFn: () async { - return await _saveImg(theme!); - }), - ), - ); + if (PlatformUtils().isDesktop) { + if(PlatformUtils().isWindows){ + OpenFile.open(showImage); + } else{ + launchUrl(Uri.file(showImage)); + } + } else { + Navigator.of(context).push( + PageRouteBuilder( + opaque: false, // set to false + pageBuilder: (_, __, ___) => ImageScreen( + imageProvider: FileImage(File(showImage)), + heroTag: heroTag, + messageID: widget.message.msgID, + downloadFn: () async { + return await _saveImg(theme!); + }), + ), + ); + } }, child: Container( constraints: @@ -344,13 +381,11 @@ class _TIMUIKitImageElem extends TIMUIKitState { child: preloadImage != null ? RawImage( image: preloadImage, - fit: BoxFit.fitWidth, - width: double.infinity, + fit: BoxFit.contain, ) : Image.file( - File(imgPath), - fit: BoxFit.fitWidth, - width: double.infinity, + File(smallImage), + fit: BoxFit.contain, ), ), )), @@ -406,35 +441,45 @@ class _TIMUIKitImageElem extends TIMUIKitState { } Widget _renderNetworkImage( - dynamic heroTag, double positionRadio, TUITheme? theme, + dynamic heroTag, double? positionRadio, TUITheme? theme, {String? path, V2TimImage? originalImg, V2TimImage? smallImg}) { try { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; String bigImgUrl = originalImg?.url ?? getBigPicUrl(); if (bigImgUrl.isEmpty && smallImg?.url != null) { bigImgUrl = smallImg!.url!; } return Stack( - alignment: widget.message.isSelf ?? false + alignment: widget.message.isSelf ?? true ? AlignmentDirectional.topEnd : AlignmentDirectional.topStart, children: [ getImage( GestureDetector( onTap: () { - Navigator.of(context).push( - PageRouteBuilder( - opaque: false, // set to false - pageBuilder: (_, __, ___) => ImageScreen( - imageProvider: CachedNetworkImageProvider( - path ?? bigImgUrl, - cacheKey: widget.message.msgID, - ), - heroTag: heroTag, - messageID: widget.message.msgID, - downloadFn: () async { - return await _saveImg(theme!); - })), - ); + if (isDesktopScreen) { + onTIMCallback(TIMCallback( + infoCode: 6660414, + infoRecommendText: TIM_t("正在下载中"), + type: TIMCallbackType.INFO + )); + } else { + Navigator.of(context).push( + PageRouteBuilder( + opaque: false, // set to false + pageBuilder: (_, __, ___) => ImageScreen( + imageProvider: CachedNetworkImageProvider( + path ?? bigImgUrl, + cacheKey: widget.message.msgID, + ), + heroTag: heroTag, + messageID: widget.message.msgID, + downloadFn: () async { + return await _saveImg(theme!); + })), + ); + } }, child: Container( constraints: @@ -474,13 +519,13 @@ class _TIMUIKitImageElem extends TIMUIKitState { bool isNeedShowLocalPath() { final current = (DateTime.now().millisecondsSinceEpoch / 1000).ceil(); final timeStamp = widget.message.timestamp ?? current; - return (widget.message.isSelf ?? false) && + return (widget.message.isSelf ?? true) && (isSent || current - timeStamp < 300); } Widget? _renderImage(dynamic heroTag, TUITheme? theme, {V2TimImage? originalImg, V2TimImage? smallImg}) { - double positionRadio = 1.0; + double? positionRadio; if (smallImg?.width != null && smallImg?.height != null && smallImg?.width != 0 && @@ -501,8 +546,12 @@ class _TIMUIKitImageElem extends TIMUIKitState { widget.message.imageElem!.path != null && widget.message.imageElem!.path!.isNotEmpty && File(widget.message.imageElem!.path!).existsSync())) { - return _renderLocalImage(widget.message.imageElem!.path!, heroTag, - networkImagePositionRadio ?? positionRadio, theme); + return _renderLocalImage( + widget.message.imageElem!.path!, + heroTag, + networkImagePositionRadio ?? positionRadio, + theme, + widget.message.imageElem!.path!); } } catch (e) { // ignore: avoid_print @@ -513,15 +562,18 @@ class _TIMUIKitImageElem extends TIMUIKitState { if (smallImg?.localUrl != null && smallImg?.localUrl != "" && File((smallImg?.localUrl!)!).existsSync()) { - return _renderLocalImage(smallImg!.localUrl!, heroTag, - networkImagePositionRadio ?? positionRadio, theme); + return _renderLocalImage(smallImg!.localUrl!, heroTag, positionRadio, + theme, originalImg?.localUrl); } } catch (e) { // ignore: avoid_print print(e); + return _renderNetworkImage(heroTag, positionRadio, theme, + smallImg: smallImg, originalImg: originalImg); } - if ((smallImg?.url ?? originalImg?.url) != null && + if ( + (smallImg?.url ?? originalImg?.url) != null && (smallImg?.url ?? originalImg?.url)!.isNotEmpty) { return _renderNetworkImage(heroTag, positionRadio, theme, smallImg: smallImg, originalImg: originalImg); diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart index 4b3336b..fb8c83a 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem.dart @@ -2,22 +2,20 @@ import 'dart:async'; import 'dart:convert'; - import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; +import 'package:tencent_extended_text/extended_text.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; - import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; - - import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/main.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem.dart'; - - import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/link_preview_entry.dart'; @@ -35,6 +33,8 @@ class TIMUIKitReplyElem extends StatefulWidget { final EdgeInsetsGeometry? textPadding; final TUIChatSeparateViewModel chatModel; final bool? isShowMessageReaction; + final bool isUseDefaultEmoji; + final List customEmojiStickerList; const TIMUIKitReplyElem({ Key? key, @@ -47,6 +47,8 @@ class TIMUIKitReplyElem extends StatefulWidget { this.isShowMessageReaction, this.backgroundColor, this.textPadding, + this.isUseDefaultEmoji = false, + this.customEmojiStickerList = const [], required this.chatModel, }) : super(key: key); @@ -63,7 +65,10 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { MessageRepliedData? _getRepliedMessage() { try { final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson( - json.decode(widget.message.cloudCustomData!)); + json.decode( + TencentUtils.checkString(widget.message.cloudCustomData) != null + ? widget.message.cloudCustomData! + : "{}")); if (messageCloudCustomData.messageReply != null) { final MessageRepliedData repliedMessage = MessageRepliedData.fromJson(messageCloudCustomData.messageReply!); @@ -81,14 +86,14 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { final messageID = cloudCustomData.messageID; final message = await widget.chatModel.findMessage(messageID); if (message != null) { - if(mounted){ + if (mounted) { setState(() { rawMessage = message; }); } } } - if(mounted){ + if (mounted) { setState(() { repliedMessage = cloudCustomData; }); @@ -104,17 +109,17 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { } _rawMessageBuilder(V2TimMessage? message, TUITheme? theme) { - if(repliedMessage == null){ + if (repliedMessage == null) { return const SizedBox(width: 0, height: 12); } if (message == null) { - if(repliedMessage?.messageAbstract != null){ + if (repliedMessage?.messageAbstract != null) { return _defaultRawMessageText(repliedMessage!.messageAbstract, theme); } return const SizedBox(width: 0, height: 12); } final messageType = message.elemType; - final isSelf = message.isSelf ?? false; + final isSelf = message.isSelf ?? true; if (widget.chatModel.abstractMessageBuilder != null) { return _defaultRawMessageText( widget.chatModel.abstractMessageBuilder!(message), @@ -148,11 +153,14 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { case MessageElemType.V2TIM_ELEM_TYPE_IMAGE: return TIMUIKitImageElem( chatModel: widget.chatModel, - message: message, isFrom: "reply", isShowMessageReaction: false); + message: message, + isFrom: "reply", + isShowMessageReaction: false); case MessageElemType.V2TIM_ELEM_TYPE_VIDEO: return TIMUIKitVideoElem(message, chatModel: widget.chatModel, - isFrom: "reply", isShowMessageReaction: false); + isFrom: "reply", + isShowMessageReaction: false); case MessageElemType.V2TIM_ELEM_TYPE_LOCATION: return _defaultRawMessageText(TIM_t("[位置]"), theme); case MessageElemType.V2TIM_ELEM_TYPE_MERGER: @@ -177,7 +185,7 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { @override void didUpdateWidget(covariant TIMUIKitReplyElem oldWidget) { - WidgetsBinding.instance?.addPostFrameCallback((mag) { + WidgetsBinding.instance.addPostFrameCallback((mag) { super.didUpdateWidget(oldWidget); _getMessageByMessageID(); }); @@ -219,44 +227,39 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { } } - Widget _renderPreviewWidget() { + Widget? _renderPreviewWidget() { // If the link preview info from [localCustomData] is available, use it to render the preview card. // Otherwise, it will returns null. if (widget.message.localCustomData != null && widget.message.localCustomData!.isNotEmpty) { - final String localJSON = widget.message.localCustomData!; - final LocalCustomDataModel? localPreviewInfo = - LocalCustomDataModel.fromMap(json.decode(localJSON)); - if (localPreviewInfo != null && !localPreviewInfo.isLinkPreviewEmpty()) { - return Container( - margin: const EdgeInsets.only(top: 8), - child: - // You can use this default widget [LinkPreviewWidget] to render preview card, or you can use custom widget. - LinkPreviewWidget(linkPreview: localPreviewInfo), - ); - } else { - return Text(widget.message.textElem?.text ?? "", - softWrap: true, - style: widget.fontStyle ?? - TextStyle( - fontSize: 16, - height: widget.chatModel.chatConfig.textHight, - )); + try { + final String localJSON = widget.message.localCustomData!; + final LocalCustomDataModel? localPreviewInfo = + LocalCustomDataModel.fromMap(json.decode(localJSON)); + if (localPreviewInfo != null && + !localPreviewInfo.isLinkPreviewEmpty()) { + return Container( + margin: const EdgeInsets.only(top: 8), + child: + // You can use this default widget [LinkPreviewWidget] to render preview card, or you can use custom widget. + LinkPreviewWidget(linkPreview: localPreviewInfo), + ); + } else { + return null; + } + } catch (e) { + return null; } } else { - return Text(widget.message.textElem?.text ?? "", - softWrap: true, - style: widget.fontStyle ?? - TextStyle( - fontSize: 16, - height: widget.chatModel.chatConfig.textHight, - )); + return null; } } @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (widget.isShowJump) { if (!isShining) { Future.delayed(Duration.zero, () { @@ -269,13 +272,17 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { } } } - final defaultStyle = (widget.message.isSelf ?? false) - ? theme.lightPrimaryMaterialColor.shade50 - : theme.weakBackgroundColor; + + final isFromSelf = widget.message.isSelf ?? true; + + final defaultStyle = isFromSelf + ? (theme.chatMessageItemFromSelfBgColor ?? + theme.lightPrimaryMaterialColor.shade50) + : (theme.chatMessageItemFromOthersBgColor); + final backgroundColor = isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) - : (widget.backgroundColor ?? defaultStyle); - final isFromSelf = widget.message.isSelf ?? false; + : (defaultStyle ?? widget.backgroundColor); final borderRadius = isFromSelf ? const BorderRadius.only( @@ -291,9 +298,13 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { final textWithLink = LinkPreviewEntry.getHyperlinksText( widget.message.textElem?.text ?? "", widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, - widget.chatModel.chatConfig.onTapLink); + onLinkTap: widget.chatModel.chatConfig.onTapLink, + isUseDefaultEmoji: widget.isUseDefaultEmoji, + customEmojiStickerList: widget.customEmojiStickerList, + isEnableTextSelection: + widget.chatModel.chatConfig.isEnableTextSelection); return Container( - padding: widget.textPadding ?? const EdgeInsets.all(10), + padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10), decoration: BoxDecoration( color: backgroundColor, borderRadius: widget.borderRadius ?? borderRadius, @@ -318,7 +329,9 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - repliedMessage != null ? "${repliedMessage!.messageSender}:" : "", + repliedMessage != null + ? "${repliedMessage!.messageSender}:" + : "", style: TextStyle( fontSize: 12, color: theme.weakTextColor, @@ -334,27 +347,31 @@ class _TIMUIKitReplyElemState extends TIMUIKitState { const SizedBox( height: 12, ), - if (widget.chatModel.chatConfig.urlPreviewType == - UrlPreviewType.none) - Text(widget.message.textElem?.text ?? "", - softWrap: true, - style: widget.fontStyle ?? - TextStyle( - fontSize: 16, - height: widget.chatModel.chatConfig.textHight, - )), - if (widget.chatModel.chatConfig.urlPreviewType == - UrlPreviewType.onlyHyperlink) - textWithLink!( - style: widget.fontStyle ?? - TextStyle( - fontSize: 16, - height: widget.chatModel.chatConfig.textHight, - )), + // If the [elemType] is text message, it will not be null here. + // You can render the widget from extension directly, with a [TextStyle] optionally. + widget.chatModel.chatConfig.urlPreviewType != UrlPreviewType.none + ? textWithLink!( + style: widget.fontStyle ?? + TextStyle( + fontSize: isDesktopScreen ? 14 : 16, + textBaseline: TextBaseline.ideographic, + height: widget.chatModel.chatConfig.textHeight)) + : ExtendedText(widget.message.textElem?.text ?? "", + softWrap: true, + style: widget.fontStyle ?? + TextStyle( + fontSize: isDesktopScreen ? 14 : 16, + height: widget.chatModel.chatConfig.textHeight), + specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( + isUseDefaultEmoji: widget.isUseDefaultEmoji, + customEmojiStickerList: widget.customEmojiStickerList, + showAtBackground: true, + )), // If the link preview info is available, render the preview card. - if (widget.chatModel.chatConfig.urlPreviewType == - UrlPreviewType.previewCardAndHyperlink) - _renderPreviewWidget(), + if (_renderPreviewWidget() != null && + widget.chatModel.chatConfig.urlPreviewType == + UrlPreviewType.previewCardAndHyperlink) + _renderPreviewWidget()!, if (widget.isShowMessageReaction ?? true) TIMUIKitMessageReactionShowPanel(message: widget.message) ], diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_sound_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_sound_elem.dart index 26d15c7..d3ab96e 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_sound_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_sound_elem.dart @@ -1,8 +1,8 @@ + import 'dart:async'; import 'dart:math'; - +import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_plugin_record_plus/const/play_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; @@ -10,11 +10,9 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_glo import 'package:tencent_cloud_chat_uikit/data_services/message/message_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.dart'; - import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/sound_record.dart'; - import 'TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart'; class TIMUIKitSoundElem extends StatefulWidget { @@ -65,13 +63,6 @@ class _TIMUIKitSoundElemState extends TIMUIKitState { _playSound() async { if (!SoundPlayer.isInited) { - // bool hasMicrophonePermission = await Permissions.checkPermission( - // context, Permission.microphone.value); - // bool hasStoragePermission = isIosDevice || - // await Permissions.checkPermission(context, Permission.storage.value); - // if (!hasMicrophonePermission || !hasStoragePermission) { - // return; - // } SoundPlayer.initSoundPlayer(); } if (widget.localCustomInt == null || @@ -81,15 +72,10 @@ class _TIMUIKitSoundElemState extends TIMUIKitState { } if (isPlaying) { SoundPlayer.stop(); - widget.chatModel.currentSelectedMsgId = ""; + widget.chatModel.currentPlayedMsgId = ""; } else { SoundPlayer.play(url: stateElement.url!); - widget.chatModel.currentSelectedMsgId = widget.msgID; - // SoundPlayer.setSoundInterruptListener(() { - // // setState(() { - // isPlaying = false; - // // }); - // }); + widget.chatModel.currentPlayedMsgId = widget.msgID; } } @@ -123,20 +109,22 @@ class _TIMUIKitSoundElemState extends TIMUIKitState { void didUpdateWidget(oldWidget) { super.didUpdateWidget(oldWidget); setState(() { - isPlaying = widget.chatModel.currentSelectedMsgId != '' && - widget.chatModel.currentSelectedMsgId == widget.msgID; + isPlaying = widget.chatModel.currentPlayedMsgId != '' && + widget.chatModel.currentPlayedMsgId == widget.msgID; }); } @override void initState() { super.initState(); - subscription = SoundPlayer.playStateListener(listener: (PlayState data) { - if (data.playState == 'complete') { - widget.chatModel.currentSelectedMsgId = ""; - // SoundPlayer.removeSoundInterruptListener(); + + subscription = + SoundPlayer.playStateListener(listener: (PlayerState state) { + if(state == PlayerState.completed){ + widget.chatModel.currentPlayedMsgId = ""; } }); + downloadMessageDetailAndSave(); } @@ -144,7 +132,7 @@ class _TIMUIKitSoundElemState extends TIMUIKitState { void dispose() { if (isPlaying) { SoundPlayer.stop(); - widget.chatModel.currentSelectedMsgId = ""; + widget.chatModel.currentPlayedMsgId = ""; } subscription?.cancel(); super.dispose(); @@ -195,9 +183,12 @@ class _TIMUIKitSoundElemState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; + final backgroundColor = widget.isFromSelf - ? theme.lightPrimaryMaterialColor.shade50 - : theme.weakBackgroundColor ?? CommonColor.weakBackgroundColor; + ? (theme.chatMessageItemFromSelfBgColor ?? + theme.lightPrimaryMaterialColor.shade50) + : (theme.chatMessageItemFromOthersBgColor); + final borderRadius = widget.isFromSelf ? const BorderRadius.only( topLeft: Radius.circular(10), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart index 29bf559..e1bed03 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_extended_text/extended_text.dart'; import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; @@ -123,9 +124,9 @@ class _TIMUIKitTextElemState extends TIMUIKitState { // The `onUpdateMessage` can use the `updateMessage()` from the [TIMUIKitChatController] directly. LinkPreviewEntry.getFirstLinkPreviewContent( message: widget.message, - onUpdateMessage: () { - widget.chatModel - .updateMessageFromController(msgID: widget.message.msgID!); + onUpdateMessage: (message) { + widget.chatModel.updateMessageFromController( + msgID: widget.message.msgID!, message: message); }); } @@ -138,7 +139,8 @@ class _TIMUIKitTextElemState extends TIMUIKitState { final String localJSON = widget.message.localCustomData!; final LocalCustomDataModel? localPreviewInfo = LocalCustomDataModel.fromMap(json.decode(localJSON)); - if (localPreviewInfo != null && !localPreviewInfo.isLinkPreviewEmpty()) { + if (localPreviewInfo != null && + !localPreviewInfo.isLinkPreviewEmpty()) { return Container( margin: const EdgeInsets.only(top: 8), child: @@ -159,13 +161,16 @@ class _TIMUIKitTextElemState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final textWithLink = LinkPreviewEntry.getHyperlinksText( - widget.message.textElem?.text ?? "", - widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, - widget.chatModel.chatConfig.onTapLink, - widget.isUseDefaultEmoji, - widget.customEmojiStickerList, - ); + widget.message.textElem?.text ?? "", + widget.chatModel.chatConfig.isSupportMarkdownForTextMessage, + onLinkTap: widget.chatModel.chatConfig.onTapLink, + isUseDefaultEmoji: widget.isUseDefaultEmoji, + customEmojiStickerList: widget.customEmojiStickerList, + isEnableTextSelection: + widget.chatModel.chatConfig.isEnableTextSelection); final borderRadius = widget.isFromSelf ? const BorderRadius.only( topLeft: Radius.circular(10), @@ -190,14 +195,18 @@ class _TIMUIKitTextElemState extends TIMUIKitState { } } } + final defaultStyle = widget.isFromSelf - ? theme.lightPrimaryMaterialColor.shade50 - : theme.chatMessageItemFromOthersBgColor; + ? (theme.chatMessageItemFromSelfBgColor ?? + theme.lightPrimaryMaterialColor.shade50) + : (theme.chatMessageItemFromOthersBgColor); + final backgroundColor = isShowJumpState ? const Color.fromRGBO(245, 166, 35, 1) - : (widget.backgroundColor ?? defaultStyle); + : (defaultStyle ?? widget.backgroundColor); + return Container( - padding: widget.textPadding ?? const EdgeInsets.all(10), + padding: widget.textPadding ?? EdgeInsets.all(isDesktopScreen ? 12 : 10), decoration: BoxDecoration( color: backgroundColor, borderRadius: widget.borderRadius ?? borderRadius, @@ -213,15 +222,15 @@ class _TIMUIKitTextElemState extends TIMUIKitState { ? textWithLink!( style: widget.fontStyle ?? TextStyle( - fontSize: 16, + fontSize: isDesktopScreen ? 14 : 16, textBaseline: TextBaseline.ideographic, - height: widget.chatModel.chatConfig.textHight)) + height: widget.chatModel.chatConfig.textHeight)) : ExtendedText(widget.message.textElem?.text ?? "", softWrap: true, style: widget.fontStyle ?? TextStyle( - fontSize: 16, - height: widget.chatModel.chatConfig.textHight), + fontSize: isDesktopScreen ? 14 : 16, + height: widget.chatModel.chatConfig.textHeight), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( isUseDefaultEmoji: widget.isUseDefaultEmoji, customEmojiStickerList: widget.customEmojiStickerList, diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart index 32ac021..a703ee5 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_extended_text/extended_text.dart'; import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; @@ -9,8 +10,6 @@ import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/link_preview_entry.dart'; -import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/widgets/link_preview.dart'; -import 'TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart'; class TIMUIKitTextTranslationElem extends StatefulWidget { final V2TimMessage message; @@ -46,25 +45,11 @@ class TIMUIKitTextTranslationElem extends StatefulWidget { State createState() => _TIMUIKitTextTranslationElemState(); } -class _TIMUIKitTextTranslationElemState extends TIMUIKitState { +class _TIMUIKitTextTranslationElemState + extends TIMUIKitState { bool isShowJumpState = false; bool isShining = false; - @override - void initState() { - super.initState(); - // get the link preview info - _getLinkPreview(); - } - - @override - void didUpdateWidget(TIMUIKitTextTranslationElem oldWidget) { - super.didUpdateWidget(oldWidget); - if (oldWidget.message.msgID == null && widget.message.msgID != null) { - _getLinkPreview(); - } - } - _showJumpColor() { if ((widget.chatModel.jumpMsgID != widget.message.msgID) && (widget.message.msgID?.isNotEmpty ?? true)) { @@ -92,73 +77,11 @@ class _TIMUIKitTextTranslationElemState extends TIMUIKitState { final TUIChatGlobalModel globalModel = serviceLocator(); final MessageService _messageService = serviceLocator(); late V2TimVideoElem stateElement = widget.message.videoElem!; + Widget errorDisplay(TUITheme? theme) { return Container( decoration: BoxDecoration( @@ -87,8 +88,7 @@ class _TIMUIKitVideoElemState extends TIMUIKitState { } } - if ((stateElement.snapshotUrl == null || - stateElement.snapshotUrl == '') && + if ((stateElement.snapshotUrl == null || stateElement.snapshotUrl == '') && (stateElement.snapshotPath == null || stateElement.snapshotPath == '')) { return Container( @@ -115,8 +115,7 @@ class _TIMUIKitVideoElemState extends TIMUIKitState { return (!kIsWeb && stateElement.snapshotUrl == null || widget.message.status == MessageStatus.V2TIM_MSG_STATUS_SENDING) ? (stateElement.snapshotPath!.isNotEmpty - ? Image.file(File(stateElement.snapshotPath!), - fit: BoxFit.fitWidth) + ? Image.file(File(stateElement.snapshotPath!), fit: BoxFit.fitWidth) : Image.file(File(stateElement.localSnapshotUrl!), fit: BoxFit.fitWidth)) : (kIsWeb || @@ -133,7 +132,7 @@ class _TIMUIKitVideoElemState extends TIMUIKitState { widget.message.videoElem!.videoUrl == '') { final response = await _messageService.getMessageOnlineUrl( msgID: widget.message.msgID!); - if(response.data != null){ + if (response.data != null) { widget.message.videoElem = response.data!.videoElem; Future.delayed(const Duration(microseconds: 10), () { setState(() => stateElement = response.data!.videoElem!); @@ -173,18 +172,47 @@ class _TIMUIKitVideoElemState extends TIMUIKitState { final heroTag = "${widget.message.msgID ?? widget.message.id ?? widget.message.timestamp ?? DateTime.now().millisecondsSinceEpoch}${widget.isFrom}"; - return GestureDetector( + return InkWell( onTap: () { - Navigator.of(context).push( - PageRouteBuilder( - opaque: false, // set to false - pageBuilder: (_, __, ___) => VideoScreen( - message: widget.message, - heroTag: heroTag, - videoElement: stateElement, + if (PlatformUtils().isDesktop) { + final videoElem = widget.message.videoElem; + if (videoElem != null) { + final localVideoUrl = TencentUtils.checkString(videoElem.localVideoUrl); + final videoPath = TencentUtils.checkString(videoElem.videoPath); + final videoUrl = videoElem.videoUrl; + + if (localVideoUrl != null) { + if(PlatformUtils().isWindows){ + OpenFile.open(localVideoUrl); + } else{ + launchUrl(Uri.file(localVideoUrl)); + } + } else if (videoPath != null) { + if(PlatformUtils().isWindows){ + OpenFile.open(videoPath); + } else{ + launchUrl(Uri.file(videoPath)); + } + } else if (TencentUtils.isTextNotEmpty(videoUrl)) { + onTIMCallback(TIMCallback( + infoCode: 6660414, + infoRecommendText: TIM_t("正在下载中"), + type: TIMCallbackType.INFO + )); + } + } + } else { + Navigator.of(context).push( + PageRouteBuilder( + opaque: false, // set to false + pageBuilder: (_, __, ___) => VideoScreen( + message: widget.message, + heroTag: heroTag, + videoElement: stateElement, + ), ), - ), - ); + ); + } }, child: Hero( tag: heroTag, @@ -220,22 +248,28 @@ class _TIMUIKitVideoElemState extends TIMUIKitState { aspectRatio: positionRadio, child: Stack( children: [ + if (stateElement.snapshotUrl != null || + stateElement.snapshotUrl != null) + AspectRatio( + aspectRatio: positionRadio, + child: Container( + decoration: const BoxDecoration( + color: Colors.transparent), + ), + ), Row( children: [ Expanded( - child: generateSnapshot( - theme, - stateElement.snapshotHeight ?? - 100)) + child: generateSnapshot(theme, + stateElement.snapshotHeight ?? 100)) ], ), if (widget.message.status != - MessageStatus - .V2TIM_MSG_STATUS_SENDING && - (stateElement.snapshotUrl != null || - stateElement.snapshotPath != - null) && - stateElement.videoPath != null || + MessageStatus + .V2TIM_MSG_STATUS_SENDING && + (stateElement.snapshotUrl != null || + stateElement.snapshotPath != null) && + stateElement.videoPath != null || stateElement.videoUrl != null) Positioned.fill( // alignment: Alignment.center, @@ -249,18 +283,14 @@ class _TIMUIKitVideoElemState extends TIMUIKitState { bottom: 10, child: Text( MessageUtils.formatVideoTime(widget - .message - .videoElem - ?.duration ?? - 0) + .message.videoElem?.duration ?? + 0) .toString(), style: const TextStyle( - color: Colors.white, - fontSize: 12))), + color: Colors.white, fontSize: 12))), ], ), - ) - ); + )); }), ))), ); diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_merger_message_elem.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_merger_message_elem.dart index e318731..498f145 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_merger_message_elem.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_merger_message_elem.dart @@ -3,14 +3,13 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart'; - - import 'package:tencent_cloud_chat_uikit/ui/widgets/merger_message_screen.dart'; - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; - import 'TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel.dart'; class TIMUIKitMergerElem extends StatefulWidget { @@ -33,7 +32,8 @@ class TIMUIKitMergerElem extends StatefulWidget { this.isShowMessageReaction, required this.messageID, required this.isShowJump, - this.clearJump, this.messageItemBuilder}) + this.clearJump, + this.messageItemBuilder}) : super(key: key); @override @@ -42,6 +42,13 @@ class TIMUIKitMergerElem extends StatefulWidget { class TIMUIKitMergerElemState extends TIMUIKitState { bool isShowJumpState = false; + late ScrollController _scrollController; + + @override + void initState() { + super.initState(); + _scrollController = ScrollController(); + } _showJumpColor() { int shineAmount = 6; @@ -69,13 +76,34 @@ class TIMUIKitMergerElemState extends TIMUIKitState { _handleTap(BuildContext context, TUIChatSeparateViewModel model) async { try { if (widget.messageID != "") { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => MergerMessageScreen( - messageItemBuilder: widget.messageItemBuilder, - model: model, msgID: widget.messageID), - )); + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + if (isDesktopScreen) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.mergerMessageList, + context: context, + width: MediaQuery.of(context).size.width * 0.7, + title: TIM_t("聊天记录"), + height: MediaQuery.of(context).size.height * 0.7, + child: (onClose) => Scrollbar( + controller: _scrollController, + child: MergerMessageScreen( + messageItemBuilder: widget.messageItemBuilder, + model: model, + msgID: widget.messageID), + ), + ); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => MergerMessageScreen( + messageItemBuilder: widget.messageItemBuilder, + model: model, + msgID: widget.messageID), + )); + } } } catch (e) { onTIMCallback(TIMCallback( @@ -101,9 +129,12 @@ class TIMUIKitMergerElemState extends TIMUIKitState { _showJumpColor(); }); } + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Container( - constraints: - BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6), + constraints: BoxConstraints( + maxWidth: + MediaQuery.of(context).size.width * (isDesktopScreen ? 0.3 : 0.6)), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel.dart new file mode 100644 index 0000000..e133996 --- /dev/null +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:scroll_to_index/scroll_to_index.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; + +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; + +class AtMemberPanel extends StatefulWidget { + /// messageList widget scroll controller + final AutoScrollController atMemberPanelScroll; + + final ValueChanged onSelectMember; + + // final TextFieldWebController textFieldWebController; + const AtMemberPanel( + // this.textFieldWebController, + {Key? key, + required this.atMemberPanelScroll, + required this.onSelectMember}) + : super(key: key); + + @override + State createState() { + return _AtMemberPanelState(); + } +} + +_getShowName(V2TimGroupMemberFullInfo? item) { + return TencentUtils.checkStringWithoutSpace(item?.nameCard) ?? + TencentUtils.checkStringWithoutSpace(item?.nickName) ?? + TencentUtils.checkStringWithoutSpace(item?.userID); +} + +class _AtMemberPanelState extends TIMUIKitState { + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; + final chatModal = Provider.of(context); + final List groupMemberList = + chatModal.showAtMemberList; + final double positionX = chatModal.atPositionX; + final double positionY = chatModal.atPositionY; + final int activeIndex = chatModal.activeAtIndex; + + if (groupMemberList.isEmpty) { + return Container(); + } + return Positioned( + left: positionX, + bottom: positionY, + child: Container( + constraints: const BoxConstraints(maxHeight: 170, maxWidth: 170), + padding: const EdgeInsets.symmetric(vertical: 5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.all(Radius.circular(8)), + border: Border.all(color: const Color(0xFFE5E6E9))), + child: Scrollbar( + controller: widget.atMemberPanelScroll, + child: ListView.builder( + shrinkWrap: true, + itemCount: groupMemberList.length, + controller: widget.atMemberPanelScroll, + itemBuilder: ((context, index) { + final memberItem = groupMemberList[index]; + if (memberItem == null) { + return AutoScrollTag( + key: ValueKey(index), + controller: widget.atMemberPanelScroll, + index: index); + } + final showName = _getShowName(memberItem); + final isAtAll = memberItem.userID == "__kImSDK_MesssageAtALL__"; + return AutoScrollTag( + key: ValueKey(index), + controller: widget.atMemberPanelScroll, + index: index, + child: Material( + color: theme.wideBackgroundColor, + child: InkWell( + onTap: () { + chatModal.activeAtIndex = index; + widget.onSelectMember(memberItem); + }, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, vertical: 4), + color: activeIndex == index + ? theme.weakBackgroundColor + : theme.wideBackgroundColor, + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24, + width: 24, + child: Avatar( + faceUrl: memberItem.faceUrl ?? "", + showName: showName), + ), + const SizedBox( + width: 8, + ), + Expanded(child: Text( + isAtAll + ? "$showName(${groupMemberList.length - 1})" + : showName, + softWrap: false, + style: TextStyle( + fontSize: 14, + overflow: TextOverflow.ellipsis, + fontWeight: memberItem.role == 400 || + memberItem.role == 300 + ? FontWeight.w500 + : FontWeight.normal, + color: memberItem.role == 400 || + memberItem.role == 300 + ? theme.primaryColor + : theme.darkTextColor), + )) + ], + ), + ), + ), + ), + ); + })), + ), + ), + ); + } +} diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_at_text.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_at_text.dart index 7257e91..d1a27eb 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_at_text.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_at_text.dart @@ -4,6 +4,7 @@ import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart'; @@ -15,14 +16,22 @@ class AtText extends StatefulWidget { final String? groupID; final V2TimGroupInfo? groupInfo; final List? groupMemberList; + final VoidCallback? closeFunc; + final Function( + V2TimGroupMemberFullInfo memberInfo, TapDownDetails? tapDetails)? + onChooseMember; + // some Group type cant @all final String? groupType; + const AtText({ this.groupID, this.groupType, Key? key, this.groupInfo, this.groupMemberList, + this.closeFunc, + this.onChooseMember, }) : super(key: key); @override @@ -47,8 +56,17 @@ class _AtTextState extends TIMUIKitState { super.dispose(); } - _onTapMemberItem(V2TimGroupMemberFullInfo memberInfo) { - Navigator.pop(context, memberInfo); + _onTapMemberItem( + V2TimGroupMemberFullInfo memberInfo, TapDownDetails? tapDetails) { + if (widget.closeFunc != null) { + widget.closeFunc!(); + } + + if (widget.onChooseMember != null) { + widget.onChooseMember!(memberInfo, tapDetails); + } else { + Navigator.pop(context, memberInfo); + } } Future> searchGroupMember( @@ -93,61 +111,62 @@ class _AtTextState extends TIMUIKitState { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - return Scaffold( - appBar: AppBar( - shadowColor: theme.weakBackgroundColor, - iconTheme: const IconThemeData( - color: Colors.white, - ), - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - leading: Row( - children: [ - IconButton( - padding: const EdgeInsets.only(left: 16), - constraints: const BoxConstraints(), - icon: Image.asset( - 'images/arrow_back.png', - package: 'tencent_cloud_chat_uikit', - height: 34, - width: 34, - ), - onPressed: () async { - Navigator.pop(context); - }, + Widget mentionedMembersBody() { + return GroupProfileMemberList( + groupType: widget.groupType ?? "", + memberList: searchMemberList ?? [], + onTapMemberItem: _onTapMemberItem, + canAtAll: true, + canSlideDelete: false, + touchBottomCallBack: () { + // Get all by once, unnecessary to load more + }, + customTopArea: PlatformUtils().isWeb + ? null + : GroupMemberSearchTextField( + onTextChange: (text) => + handleSearchGroupMembers(text, context), + )); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: mentionedMembersBody(), + defaultWidget: Scaffold( + appBar: AppBar( + shadowColor: theme.weakBackgroundColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + ), + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + leading: Row( + children: [ + IconButton( + padding: const EdgeInsets.only(left: 16), + constraints: const BoxConstraints(), + icon: Image.asset( + 'images/arrow_back.png', + package: 'tencent_cloud_chat_uikit', + height: 34, + width: 34, + color: theme.appbarTextColor, + ), + onPressed: () async { + Navigator.pop(context); + }, + ), + ], + ), + centerTitle: true, + leadingWidth: 100, + title: Text( + TIM_t("选择提醒人"), + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 17, + ), ), - ], - ), - centerTitle: true, - leadingWidth: 100, - title: Text( - TIM_t("选择提醒人"), - style: const TextStyle( - color: Colors.white, - fontSize: 17, ), - ), - ), - body: GroupProfileMemberList( - groupType: widget.groupType ?? "", - memberList: searchMemberList ?? [], - onTapMemberItem: _onTapMemberItem, - canAtAll: true, - canSlideDelete: false, - touchBottomCallBack: () { - // Get all by once, unnecessary to load more - }, - customTopArea: PlatformUtils().isWeb - ? null - : GroupMemberSearchTextField( - onTextChange: (text) => - handleSearchGroupMembers(text, context), - ))); + body: mentionedMembersBody())); } } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list.dart index 54afc63..2229fc8 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list.dart @@ -135,26 +135,20 @@ class _SelectCallInviterState extends TIMUIKitState { return Scaffold( appBar: AppBar( shadowColor: theme.weakBackgroundColor, - iconTheme: const IconThemeData( - color: Colors.white, - ), - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), + iconTheme: IconThemeData( + color: theme.appbarTextColor, ), + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, leading: TextButton( onPressed: () { Navigator.pop(context); }, child: Text( TIM_t("取消"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 14, ), ), ), @@ -167,19 +161,19 @@ class _SelectCallInviterState extends TIMUIKitState { }, child: Text( TIM_t("完成"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 14, ), ), ) ], centerTitle: true, - leadingWidth: 100, + leadingWidth: 80, title: Text( TIM_t("发起呼叫"), - style: const TextStyle( - color: Colors.white, + style: TextStyle( + color: theme.appbarTextColor, fontSize: 17, ), ), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart index bafa2b0..a1df2dd 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart @@ -77,6 +77,7 @@ class EmojiItem extends TIMUIKitStatelessWidget { return DefaultTextStyle( style: TextStyle( fontSize: (PlatformUtils().isAndroid) ? 20 : 26, + color: hexToColor("f9453d") ), child: Text( String.fromCharCode(unicode), diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart index 8d53497..78c2d89 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart @@ -1,35 +1,33 @@ // ignore_for_file: unused_field, avoid_print, unused_import import 'dart:io'; - +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:fc_native_video_thumbnail_for_us/fc_native_video_thumbnail_for_us.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:image_picker/image_picker.dart'; import 'package:file_picker/file_picker.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; -import 'package:tencent_im_base/tencent_im_base.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list.dart'; import 'package:tencent_wechat_camera_picker/tencent_wechat_camera_picker.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; - +import 'package:path/path.dart' as p; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; - import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; - import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/intl_camer_picker.dart'; -import 'package:video_thumbnail/video_thumbnail.dart' as video_thumbnail; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; + // ignore: unnecessary_import import 'dart:typed_data'; - import 'package:universal_html/html.dart' as html; class MorePanelConfig { @@ -38,6 +36,8 @@ class MorePanelConfig { final bool showFilePickAction; final bool showWebImagePickAction; final bool showWebVideoPickAction; + final bool showVoiceCall; + final bool showVideoCall; final List? extraAction; final Widget Function(MorePanelItem item)? actionBuilder; @@ -47,6 +47,8 @@ class MorePanelConfig { this.showCameraAction = true, this.showWebImagePickAction = true, this.showWebVideoPickAction = true, + this.showVoiceCall = true, + this.showVideoCall = true, this.extraAction, this.actionBuilder, }); @@ -77,6 +79,7 @@ class MorePanel extends StatefulWidget { Key? key, this.morePanelConfig}) : super(key: key); + @override State createState() => _MorePanelState(); } @@ -88,11 +91,28 @@ class _MorePanelState extends TIMUIKitState { Uint8List? fileContent; String? fileName; File? tempFile; + final _tUICore = TUICore(); + final _tUILogin = TUILogin(); + bool isInstallCallkit = false; + final ScrollController _scrollController = ScrollController(); + final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + + @override + void initState() { + super.initState(); + if (PlatformUtils().isMobile) { + _tUICore.getService(TUICALLKIT_SERVICE_NAME).then((value) { + setState(() { + isInstallCallkit = value; + }); + }); + } + } List itemList(TUIChatSeparateViewModel model, TUITheme theme) { final config = widget.morePanelConfig ?? MorePanelConfig(); return [ - if (!PlatformUtils().isWeb) + if (PlatformUtils().isMobile) MorePanelItem( id: "screen", title: TIM_t("拍摄"), @@ -212,6 +232,58 @@ class _MorePanelState extends TIMUIKitState { width: 64, ), )), + if (isInstallCallkit && PlatformUtils().isMobile) + MorePanelItem( + id: "videoCall", + title: TIM_t("视频通话"), + onTap: (c) { + _onFeatureTap( + "videoCall", + c, + model, + theme, + ); + }, + icon: Container( + height: 64, + width: 64, + margin: const EdgeInsets.only(bottom: 4), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(5))), + child: SvgPicture.asset( + "images/video-call.svg", + package: 'tencent_cloud_chat_uikit', + height: 64, + width: 64, + ), + )), + if (isInstallCallkit && PlatformUtils().isMobile) + MorePanelItem( + id: "voiceCall", + title: TIM_t("语音通话"), + onTap: (c) { + _onFeatureTap( + "voiceCall", + c, + model, + theme, + ); + }, + icon: Container( + height: 64, + width: 64, + margin: const EdgeInsets.only(bottom: 4), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(5))), + child: SvgPicture.asset( + "images/voice-call.svg", + package: 'tencent_cloud_chat_uikit', + height: 64, + width: 64, + ), + )), if (config.extraAction != null) ...?config.extraAction, ].where((element) { if (element.id == "screen") { @@ -233,11 +305,18 @@ class _MorePanelState extends TIMUIKitState { if (element.id == "video") { return config.showWebVideoPickAction; } + if (element.id == "voiceCall") { + return config.showVoiceCall; + } + if (element.id == "videoCall") { + return config.showVideoCall; + } return true; }).toList(); } _sendVideoMessage(AssetEntity asset, TUIChatSeparateViewModel model) async { + final plugin = FcNativeVideoThumbnail(); final originFile = await asset.originFile; final size = await originFile!.length(); if (size >= 104857600) { @@ -253,21 +332,24 @@ class _MorePanelState extends TIMUIKitState { final convID = widget.conversationID; final convType = widget.conversationType; - String tempPath = (await getTemporaryDirectory()).path; + String tempPath = (await getTemporaryDirectory()).path + + p.basename(originFile.path) + + ".jpeg"; - String? thumbnail = await video_thumbnail.VideoThumbnail.thumbnailFile( - video: originFile.path, - thumbnailPath: tempPath, - imageFormat: video_thumbnail.ImageFormat.JPEG, - maxWidth: - 128, // specify the width of the thumbnail, let the height auto-scaled to keep the source aspect ratio - quality: 25, + await plugin.getVideoThumbnail( + srcFile: originFile.path, + keepAspectRatio: true, + destFile: tempPath, + format: 'jpeg', + width: 128, + quality: 100, + height: 128, ); MessageUtils.handleMessageError( model.sendVideoMessage( videoPath: filePath, duration: duration, - snapshotPath: thumbnail ?? '', + snapshotPath: tempPath, convID: convID, convType: convType), context); @@ -275,36 +357,92 @@ class _MorePanelState extends TIMUIKitState { _sendImageMessage(TUIChatSeparateViewModel model, TUITheme theme) async { try { - final bool isAndroid = PlatformUtils().isAndroid; - if (!PlatformUtils().isWeb && - !await Permissions.checkPermission( - context, - isAndroid ? Permission.storage.value : Permission.photos.value, - theme, - )) { - return; - } - final convID = widget.conversationID; - final convType = widget.conversationType; - final pickedAssets = await AssetPicker.pickAssets(context); - - if (pickedAssets != null) { - for (var asset in pickedAssets) { - final originFile = await asset.originFile; - final filePath = originFile?.path; - final type = asset.type; - if (filePath != null) { - if (type == AssetType.image) { - MessageUtils.handleMessageError( - model.sendImageMessage( - imagePath: filePath, convID: convID, convType: convType), - context); + if (PlatformUtils().isMobile){ + if(PlatformUtils().isAndroid){ + AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; + if ((androidInfo.version.sdkInt ?? 0) >= 33) { + final videos = await Permissions.checkPermission( + context,Permission.videos.value, + theme, + ); + final photos = await Permissions.checkPermission( + context,Permission.photos.value, + theme, + ); + if(!videos && !photos){ + return; } - - if (type == AssetType.video) { - _sendVideoMessage(asset, model); + } else { + final storage = await Permissions.checkPermission( + context, Permission.storage.value, + theme, + ); + if(!storage){ + return; } } + }else{ + final photos = await Permissions.checkPermission( + context, + Permission.photos.value, + theme, + ); + if(!photos){ + return; + } + } + } + + final convID = widget.conversationID; + final convType = widget.conversationType; + + if (PlatformUtils().isMobile) { + final pickedAssets = await AssetPicker.pickAssets(context); + + if (pickedAssets != null) { + for (var asset in pickedAssets) { + final originFile = await asset.originFile; + final filePath = originFile?.path; + final type = asset.type; + if (filePath != null) { + if (type == AssetType.image) { + MessageUtils.handleMessageError( + model.sendImageMessage( + imagePath: filePath, + convID: convID, + convType: convType), + context); + } + + if (type == AssetType.video) { + _sendVideoMessage(asset, model); + } + } + } + } + } else { + FilePickerResult? result = + await FilePicker.platform.pickFiles(type: FileType.media); + if (result != null && result.files.isNotEmpty) { + File file = File(result.files.single.path!); + final String savePath = file.path; + final String type = TencentUtils.getFileType( + savePath.split(".")[savePath.split(".").length - 1]) + .split("/")[0]; + + if (type == "image") { + MessageUtils.handleMessageError( + model.sendImageMessage( + imagePath: savePath, convID: convID, convType: convType), + context); + } else if (type == "video") { + MessageUtils.handleMessageError( + model.sendVideoMessage( + videoPath: savePath, convID: convID, convType: convType), + context); + } + } else { + throw TypeError(); } } } catch (err) { @@ -317,14 +455,18 @@ class _MorePanelState extends TIMUIKitState { TUITheme theme, ) async { try { - if (PlatformUtils().isIOS && - !await Permissions.checkPermission( + if (!await Permissions.checkPermission( context, Permission.camera.value, theme, )) { return; } + await Permissions.checkPermission( + context, + Permission.microphone.value, + theme, + ); final convID = widget.conversationID; final convType = widget.conversationType; final pickedFile = await CameraPicker.pickFromCamera(context, @@ -417,14 +559,6 @@ class _MorePanelState extends TIMUIKitState { TUIChatSeparateViewModel model, TUITheme theme, ) async { - if (!kIsWeb && - !await Permissions.checkPermission( - context, - Permission.storage.value, - theme, - )) { - return; - } try { final convID = widget.conversationID; final convType = widget.conversationType; @@ -462,7 +596,7 @@ class _MorePanelState extends TIMUIKitState { convType: convType), context); } else { - throw NullThrownError(); + throw TypeError(); } } catch (e) { print("_sendFileErr: ${e.toString()}"); @@ -493,6 +627,53 @@ class _MorePanelState extends TIMUIKitState { // only for web _sendVideoFileOnWeb(model); break; + case "voiceCall": + _goToVideoUI(TYPE_AUDIO); + break; + case "videoCall": + _goToVideoUI(TYPE_VIDEO); + break; + } + } + + _goToVideoUI(String type) async { + if (!PlatformUtils().isWeb) { + final hasCameraPermission = type == TYPE_VIDEO + ? await Permissions.checkPermission(context, Permission.camera.value) + : true; + final hasMicphonePermission = await Permissions.checkPermission( + context, Permission.microphone.value); + if (!hasCameraPermission || !hasMicphonePermission) { + return; + } + } + + final isGroup = widget.conversationType == ConvType.group; + if (isGroup) { + List? selectedMember = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SelectCallInviter( + groupID: widget.conversationID, + ), + ), + ); + if (selectedMember != null) { + final inviteMember = selectedMember.map((e) => e.userID).toList(); + _tUICore.callService(TUICALLKIT_SERVICE_NAME, METHOD_NAME_CALL, { + PARAM_NAME_TYPE: type, + PARAM_NAME_USERIDS: inviteMember, + PARAM_NAME_GROUPID: widget.conversationType == ConvType.group + ? widget.conversationID + : "" + }); + } + } else { + _tUICore.callService(TUICALLKIT_SERVICE_NAME, METHOD_NAME_CALL, { + PARAM_NAME_TYPE: type, + PARAM_NAME_USERIDS: [widget.conversationID], + PARAM_NAME_GROUPID: "" + }); } } @@ -512,42 +693,46 @@ class _MorePanelState extends TIMUIKitState { ), padding: const EdgeInsets.only(top: 20, left: 20, right: 20), width: screenWidth, - child: SingleChildScrollView( - child: Wrap( - spacing: (screenWidth - (23 * 2) - 64 * 4) / 3, - runSpacing: 20, - children: itemList(model, theme) - .map((item) => InkWell( - onTap: () { - if (item.onTap != null) { - item.onTap!(context); - } - }, - child: widget.morePanelConfig?.actionBuilder != null - ? widget.morePanelConfig?.actionBuilder!(item) - : SizedBox( - height: 94, - width: 64, - child: Column( - children: [ - Container( - height: 64, - width: 64, - margin: const EdgeInsets.only(bottom: 4), - decoration: const BoxDecoration( - borderRadius: - BorderRadius.all(Radius.circular(5))), - child: item.icon, - ), - Text( - item.title, - style: TextStyle( - fontSize: 12, color: theme.darkTextColor), - ) - ], - ), - ))) - .toList(), + child: Scrollbar( + controller: _scrollController, + child: SingleChildScrollView( + controller: _scrollController, + child: Wrap( + spacing: (screenWidth - (23 * 2) - 64 * 4) / 3, + runSpacing: 20, + children: itemList(model, theme) + .map((item) => InkWell( + onTap: () { + if (item.onTap != null) { + item.onTap!(context); + } + }, + child: widget.morePanelConfig?.actionBuilder != null + ? widget.morePanelConfig?.actionBuilder!(item) + : SizedBox( + height: 94, + width: 64, + child: Column( + children: [ + Container( + height: 64, + width: 64, + margin: const EdgeInsets.only(bottom: 4), + decoration: const BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(5))), + child: item.icon, + ), + Text( + item.title, + style: TextStyle( + fontSize: 12, color: theme.darkTextColor), + ) + ], + ), + ))) + .toList(), + ), ), ), ); diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart index faae46b..bcd1a2e 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart @@ -129,7 +129,7 @@ class _SendSoundMessageState extends TIMUIKitState { ), ); }); - Overlay.of(context)!.insert(overlayEntry!); + Overlay.of(context)?.insert(overlayEntry!); } } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart index 93b23eb..5c5d473 100644 --- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field.dart @@ -1,11 +1,11 @@ import 'dart:async'; import 'dart:math'; +import 'package:diff_match_patch/diff_match_patch.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart'; -import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; -import 'package:tencent_extended_text_field/extended_text_field.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; @@ -18,15 +18,28 @@ import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_at_text.dart'; -import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; -import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart'; -import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; -import 'package:tencent_keyboard_visibility/tencent_keyboard_visibility.dart'; -import 'special_text/DefaultSpecialTextSpanBuilder.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart'; enum MuteStatus { none, me, all } +typedef CustomStickerPanel = Widget Function({ + void Function() sendTextMessage, + void Function(int index, String data) sendFaceMessage, + void Function() deleteText, + void Function(int unicode) addText, + void Function(String singleEmojiName) addCustomEmojiText, + List defaultCustomEmojiStickerList, + + /// If non-null, requires the child to have exactly this width. + double? width, + + /// If non-null, requires the child to have exactly this height. + double? height, +}); + +GlobalKey<_InputTextFieldState> inputTextFieldState = GlobalKey(); + class TIMUIKitInputTextField extends StatefulWidget { /// conversation id final String conversationID; @@ -40,6 +53,9 @@ class TIMUIKitInputTextField extends StatefulWidget { /// messageList widget scroll controller final AutoScrollController? scrollController; + /// messageList widget scroll controller + final AutoScrollController? atMemberPanelScroll; + /// hint text for textField widget final String? hintText; @@ -71,17 +87,13 @@ class TIMUIKitInputTextField extends StatefulWidget { final List customEmojiStickerList; - final String? groupType; - /// sticker panel customization - final Widget Function( - {void Function() sendTextMessage, - void Function(int index, String data) sendFaceMessage, - void Function() deleteText, - void Function(int unicode) addText, - void Function(String singleEmojiName) addCustomEmojiText, - List defaultCustomEmojiStickerList})? - customStickerPanel; + final CustomStickerPanel? customStickerPanel; + + /// Conversation need search + final V2TimConversation currentConversation; + + final String? groupType; const TIMUIKitInputTextField( {Key? key, @@ -100,7 +112,10 @@ class TIMUIKitInputTextField extends StatefulWidget { this.onChanged, this.isUseDefaultEmoji = false, this.customEmojiStickerList = const [], - required this.model, this.groupType}) + required this.model, + required this.currentConversation, + this.groupType, + this.atMemberPanelScroll}) : super(key: key); @override @@ -110,18 +125,14 @@ class TIMUIKitInputTextField extends StatefulWidget { class _InputTextFieldState extends TIMUIKitState { final TUIChatGlobalModel globalModel = serviceLocator(); final TUISettingModel settingModel = serviceLocator(); - bool showMore = false; - bool showMoreButton = true; - bool showSendSoundText = false; - bool showEmojiPanel = false; - bool showKeyboard = false; + final RegExp atTextReg = RegExp(r'@([^@\s]*)'); late FocusNode focusNode; String zeroWidthSpace = '\ufeff'; String lastText = ""; String languageType = ""; - double? bottomPadding; - Function? setKeyboardHeight; int? currentCursor; + bool isAddingAtSearchWords = false; + double inputWidth = 900; Map memberInfoMap = {}; @@ -133,56 +144,8 @@ class _InputTextFieldState extends TIMUIKitState { int latestSendEditStatusTime = DateTime.now().millisecondsSinceEpoch; - Widget _getBottomContainer() { - if (showEmojiPanel) { - return widget.customStickerPanel != null - ? widget.customStickerPanel!( - sendTextMessage: () { - onEmojiSubmitted(); - }, - sendFaceMessage: onCustomEmojiFaceSubmitted, - deleteText: () { - backSpaceText(); - }, - addText: (int unicode) { - final newText = String.fromCharCode(unicode); - addStickerToText(newText); - // handleSetDraftText(); - }, - addCustomEmojiText: ((String singleEmojiName) { - String? emojiName = singleEmojiName.split('.png')[0]; - if (widget.isUseDefaultEmoji && - languageType == 'zh' && - ConstData.emojiMapList[emojiName] != null && - ConstData.emojiMapList[emojiName] != '') { - emojiName = ConstData.emojiMapList[emojiName]; - } - final newText = '[$emojiName]'; - addStickerToText(newText); - setSendButton(); - }), - defaultCustomEmojiStickerList: - widget.isUseDefaultEmoji ? ConstData.emojiList : []) - : EmojiPanel(onTapEmoji: (unicode) { - final newText = String.fromCharCode(unicode); - addStickerToText(newText); - setSendButton(); - // handleSetDraftText(); - }, onSubmitted: () { - onEmojiSubmitted(); - }, delete: () { - backSpaceText(); - }); - } - - if (showMore) { - return MorePanel( - morePanelConfig: widget.morePanelConfig, - conversationID: widget.conversationID, - conversationType: widget.conversationType); - } - - return const SizedBox(height: 0); + setCurrentCursor(int? value) { + currentCursor = value; } void addStickerToText(String sticker) { @@ -195,59 +158,10 @@ class _InputTextFieldState extends TIMUIKitState { } else { textEditingController.text = "$oldText$sticker"; } - } - double _getBottomHeight() { - if (showKeyboard) { - final currentKeyboardHeight = MediaQuery.of(context).viewInsets.bottom; - double originHeight = settingModel.keyboardHeight; - if (currentKeyboardHeight != 0) { - if (currentKeyboardHeight >= originHeight) { - originHeight = currentKeyboardHeight; - } - if (setKeyboardHeight != null) { - setKeyboardHeight!(currentKeyboardHeight); - } - } - final height = originHeight != 0 ? originHeight : currentKeyboardHeight; - return height; - } else if (showMore || showEmojiPanel) { - return 248.0 + (bottomPadding ?? 0.0); - } else if (textEditingController.text.length >= 46 && - showKeyboard == false) { - return 25 + (bottomPadding ?? 0.0); - } else { - return bottomPadding ?? 0; - } - } - - _openMore() { - if (!showMore) { - focusNode.unfocus(); - currentCursor = null; - } - setState(() { - showKeyboard = false; - showEmojiPanel = false; - showSendSoundText = false; - showMore = !showMore; - }); - } - - _openEmojiPanel() { - _onCursorChange(); - showKeyboard = showEmojiPanel; - if (showEmojiPanel) { - focusNode.requestFocus(); - } else { + if (TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop) { focusNode.unfocus(); } - - setState(() { - showMore = false; - showSendSoundText = false; - showEmojiPanel = !showEmojiPanel; - }); } String _filterU200b(String text) { @@ -255,18 +169,17 @@ class _InputTextFieldState extends TIMUIKitState { } getShowName(message) { - return message.friendRemark == null || message.friendRemark == '' - ? message.nickName == null || message.nickName == '' - ? message.sender - : message.nickName - : message.friendRemark; + return TencentUtils.checkStringWithoutSpace(message?.friendRemark) ?? + TencentUtils.checkStringWithoutSpace(message?.nickName) ?? + TencentUtils.checkStringWithoutSpace(message?.userID); } - handleSetDraftText() async { - String convID = widget.conversationID; - String conversationID = widget.conversationType == ConvType.c2c - ? "c2c_$convID" - : "group_$convID"; + handleSetDraftText([String? id, ConvType? convType]) async { + String convID = id ?? widget.conversationID; + String conversationID = + (convType ?? widget.conversationType) == ConvType.c2c + ? "c2c_$convID" + : "group_$convID"; String text = textEditingController.text; String? draftText = _filterU200b(text); @@ -277,59 +190,6 @@ class _InputTextFieldState extends TIMUIKitState { conversationID: conversationID, draftText: draftText); } - _buildRepliedMessage(V2TimMessage? repliedMessage) { - final haveRepliedMessage = repliedMessage != null; - if (haveRepliedMessage) { - final text = - "${MessageUtils.getDisplayName(widget.model.repliedMessage!)}:${widget.model.abstractMessageBuilder != null ? widget.model.abstractMessageBuilder!(widget.model.repliedMessage!) : MessageUtils.getAbstractMessageAsync(widget.model.repliedMessage!, widget.model.groupMemberList ?? [])}"; - return Container( - color: widget.backgroundColor ?? hexToColor("f5f5f6"), - alignment: Alignment.centerLeft, - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - text, - softWrap: true, - maxLines: 3, - overflow: TextOverflow.ellipsis, - style: TextStyle(color: hexToColor("8f959e"), fontSize: 14), - ), - ), - const SizedBox( - width: 16, - ), - InkWell( - onTap: () { - widget.model.repliedMessage = null; - }, - child: Icon(Icons.clear, color: hexToColor("8f959e"), size: 18), - ) - ], - ), - ); - } - return Container(); - } - - void setSendButton() { - final value = textEditingController.text; - if (isWebDevice() || isAndroidDevice()) { - if (value.isEmpty && showMoreButton != true) { - setState(() { - showMoreButton = true; - }); - } else if (value.isNotEmpty && showMoreButton == true) { - setState(() { - showMoreButton = false; - }); - } - } - } - backSpaceText() { String originalText = textEditingController.text; dynamic text; @@ -339,32 +199,38 @@ class _InputTextFieldState extends TIMUIKitState { // _addDeleteTag(); } else { text = originalText.characters.skipLast(1); - textEditingController.text = "$text"; + textEditingController.text = text; // handleSetDraftText(); } - setSendButton(); } // 和onSubmitted一样,只是保持焦点的不同 onEmojiSubmitted() { + lastText = ""; final text = textEditingController.text.trim(); final convType = widget.conversationType; if (text.isNotEmpty && text != zeroWidthSpace) { if (widget.model.repliedMessage != null) { MessageUtils.handleMessageError( widget.model.sendReplyMessage( - text: text, convID: widget.conversationID, convType: convType), + text: text, + convID: widget.conversationID, + convType: convType, + atUserIDList: getUserIdFromMemberInfoMap(), + ), context); } else { MessageUtils.handleMessageError( widget.model.sendTextMessage( - text: text, convID: widget.conversationID, convType: convType), + text: text, + convID: widget.conversationID, + convType: convType, + ), context); } textEditingController.clear(); goDownBottom(); } - setSendButton(); currentCursor = null; } @@ -400,13 +266,17 @@ class _InputTextFieldState extends TIMUIKitState { } onSubmitted() async { + lastText = ""; final text = textEditingController.text.trim(); final convType = widget.conversationType; if (text.isNotEmpty && text != zeroWidthSpace) { if (widget.model.repliedMessage != null) { MessageUtils.handleMessageError( widget.model.sendReplyMessage( - text: text, convID: widget.conversationID, convType: convType), + text: text, + convID: widget.conversationID, + convType: convType, + atUserIDList: getUserIdFromMemberInfoMap()), context); } else if (memberInfoMap.isNotEmpty) { widget.model.sendTextAtMessage( @@ -422,23 +292,17 @@ class _InputTextFieldState extends TIMUIKitState { } textEditingController.clear(); currentCursor = null; - if (showKeyboard) { - focusNode.requestFocus(); - } lastText = ""; memberInfoMap = {}; - setState(() { - if (textEditingController.text.isEmpty) { - showMoreButton = true; - } - }); + goDownBottom(); _handleSendEditStatus("", false); } } void goDownBottom() { - if(globalModel.getMessageListPosition(widget.conversationID) == HistoryMessagePosition.notShowLatest){ + if (globalModel.getMessageListPosition(widget.conversationID) == + HistoryMessagePosition.notShowLatest) { return; } Future.delayed(const Duration(milliseconds: 50), () { @@ -450,35 +314,20 @@ class _InputTextFieldState extends TIMUIKitState { curve: Curves.ease, ); } - } catch (e) { - // ignore: avoid_print - print(e); - } + // ignore: empty_catches + } catch (e) {} }); } - _hideAllPanel() { - focusNode.unfocus(); - currentCursor == null; - if (showKeyboard != false || showMore != false || showEmojiPanel != false) { - setState(() { - showKeyboard = false; - showMore = false; - showEmojiPanel = false; - }); - } - } - void onModelChanged() { if (widget.model.repliedMessage != null) { - showKeyboard = true; + narrowTextFieldKey.currentState?.showKeyboard = true; focusNode.requestFocus(); _addDeleteTag(); } else {} if (widget.model.editRevokedMsg != "") { - showKeyboard = true; + narrowTextFieldKey.currentState?.showKeyboard = true; focusNode.requestFocus(); - textEditingController.clear(); textEditingController.text = widget.model.editRevokedMsg; textEditingController.selection = TextSelection.fromPosition(TextPosition( affinity: TextAffinity.downstream, @@ -505,15 +354,11 @@ class _InputTextFieldState extends TIMUIKitState { } } - _getShowName(V2TimGroupMemberFullInfo? item) { - final nameCard = item?.nameCard ?? ""; - final nickName = item?.nickName ?? ""; - final userID = item?.userID ?? ""; - return nameCard.isNotEmpty - ? nameCard - : nickName.isNotEmpty - ? nickName - : userID; + String _getShowName(V2TimGroupMemberFullInfo? item) { + return TencentUtils.checkStringWithoutSpace(item?.nameCard) ?? + TencentUtils.checkStringWithoutSpace(item?.nickName) ?? + TencentUtils.checkStringWithoutSpace(item?.userID) ?? + ""; } _longPressToAt(String? userID, String? nickName) { @@ -523,47 +368,145 @@ class _InputTextFieldState extends TIMUIKitState { ); final showName = _getShowName(memberInfo); memberInfoMap["@$showName"] = memberInfo; - String text = "$lastText@$showName "; + String text = "${textEditingController.text}@$showName "; //please do not delete space + focusNode.requestFocus(); textEditingController.text = text; textEditingController.selection = - TextSelection.fromPosition(TextPosition(offset: text.length)); + TextSelection.fromPosition(TextPosition(offset: text.length - 1)); lastText = text; } + bool shouldRemoveAtTag(String atTag, String deletedChar) { + final atMemberArray = []; + memberInfoMap.forEach((key, value) { + atMemberArray.add(key); + }); + for (String member in atMemberArray) { + if (atTag == member && member.contains(deletedChar)) { + return true; + } + } + return false; + } + + Offset getAtPosition(String text, int atPlace) { + final textBeforeAt = text.substring(0, atPlace + 1); + final textPainter = TextPainter( + text: TextSpan(text: textBeforeAt, style: const TextStyle(fontSize: 14)), + textDirection: TextDirection.ltr, + maxLines: null, + ); + textPainter.layout(maxWidth: inputWidth); + final TextPosition lastLineOffset = textPainter + .getPositionForOffset(Offset(textPainter.width, textPainter.height)); + final Offset caretPosition = + textPainter.getOffsetForCaret(lastLineOffset, Rect.zero); + final dx = min(inputWidth - 180, caretPosition.dx + 16); + final dy = max(24, 110 - caretPosition.dy).toDouble(); + + return Offset(dx, dy); + } + + calculateRemoveRemainAt(String text) { + Map map = {}; + Iterable matches = atTextReg.allMatches(text); + List parseAtList = []; + for (final item in matches) { + final str = item.group(0); + parseAtList.add(str); + } + for (String? key in parseAtList) { + if (key != null && memberInfoMap[key] != null) { + map[key] = memberInfoMap[key]!; + } + } + memberInfoMap = map; + } + _handleAtText(String text, TUIChatSeparateViewModel model) async { + final text = textEditingController.text; String? groupID = widget.conversationType == ConvType.group ? widget.conversationID : null; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (groupID == null) { lastText = text; return; } - RegExp atTextReg = RegExp(r'@([^@\s]*)'); - int textLength = text.length; // 删除的话 - if (lastText.length > textLength && text != "@") { - Map map = {}; - Iterable matches = atTextReg.allMatches(text); - List parseAtList = []; - for (final item in matches) { - final str = item.group(0); - parseAtList.add(str); - } - for (String? key in parseAtList) { - if (key != null && memberInfoMap[key] != null) { - map[key] = memberInfoMap[key]!; + if (lastText.length > textLength) { + final List differencesList = diff(lastText, text); + final diffIndex = differencesList.first.text.length - 1; + int atIndex = lastText.lastIndexOf('@', diffIndex); + int spaceIndex = lastText.indexOf(' ', diffIndex); + if (diffIndex < 0 || atIndex < 0 || spaceIndex <= atIndex) { + lastText = text; + } else { + String atTag = lastText.substring(atIndex, spaceIndex); + String deletedChar = lastText[diffIndex]; + if (shouldRemoveAtTag(atTag, deletedChar)) { + final newText = lastText.substring(0, atIndex) + + lastText.substring(spaceIndex + 1); + textEditingController.text = newText; + textEditingController.selection = + TextSelection.collapsed(offset: atIndex); + lastText = newText; + Map map = {}; + Iterable matches = atTextReg.allMatches(text); + List parseAtList = []; + for (final item in matches) { + final str = item.group(0); + parseAtList.add(str); + } + for (String? key in parseAtList) { + if (key != null && memberInfoMap[key] != null) { + map[key] = memberInfoMap[key]!; + } + } + memberInfoMap = map; + return; } } - memberInfoMap = map; } - // 有@的情况并且是文本新增的时候 - if (textLength > 0 && + + if (isDesktopScreen) { + final atPlace = text.lastIndexOf("@"); + final keyword = text.substring(atPlace + 1); + if (atPlace >= 0) { + if (text[textLength - 1] == "@") { + final atPosition = getAtPosition(text, atPlace); + model.atPositionX = atPosition.dx; + model.atPositionY = atPosition.dy; + isAddingAtSearchWords = true; + } + final List showAtMemberList = + (model.groupMemberList ?? []).where((element) { + final friendRemark = element?.friendRemark ?? ""; + final nickName = element?.nickName ?? ""; + final showName = TencentUtils.checkString(friendRemark) ?? + TencentUtils.checkString(nickName) ?? + TencentUtils.checkString(element?.userID) ?? + ""; + return showName.contains(keyword); + }).toList(); + + model.activeAtIndex = 0; + model.showAtMemberList = showAtMemberList; + + isAddingAtSearchWords = showAtMemberList.isNotEmpty; + } else { + model.activeAtIndex = -1; + model.showAtMemberList = []; + isAddingAtSearchWords = false; + } + } else if (textLength > 0 && text[textLength - 1] == "@" && - (lastText.length < textLength || text == "@")) { + lastText.length < textLength) { V2TimGroupMemberFullInfo? memberInfo = await Navigator.push( context, MaterialPageRoute( @@ -577,38 +520,104 @@ class _InputTextFieldState extends TIMUIKitState { final showName = _getShowName(memberInfo); if (memberInfo != null) { memberInfoMap["@$showName"] = memberInfo; - //please don not delete space textEditingController.text = "$text$showName "; + lastText = "$text$showName "; } } - lastText = text; + lastText = textEditingController.text; } - _debounce( - Function(String text) fun, [ - Duration delay = const Duration(milliseconds: 30), - ]) { - Timer? timer; - return (String text) { - if (timer != null) { - timer?.cancel(); - } + void replaceAtTag(String selectedMember) { + int cursorPosition = textEditingController.selection.baseOffset; + int atIndex = + textEditingController.text.lastIndexOf('@', cursorPosition - 1); + if (atIndex >= 0) { + String beforeAt = textEditingController.text.substring(0, atIndex); + String afterAt = textEditingController.text.substring(cursorPosition); + textEditingController.text = + beforeAt + '@' + selectedMember + ' ' + afterAt; + textEditingController.selection = + TextSelection.collapsed(offset: atIndex + selectedMember.length + 2); + lastText = beforeAt + '@' + selectedMember + ' ' + afterAt; + } + } - timer = Timer(delay, () { - fun(text); - }); - }; + void handleAtMember( + {V2TimGroupMemberFullInfo? memberInfo, + bool? isAddToCursorPosition = false}) { + if (memberInfo != null) { + final String showName = _getShowName(memberInfo); + memberInfoMap["@$showName"] = memberInfo; + replaceAtTag(showName); + widget.model.showAtMemberList = []; + widget.model.activeAtIndex = -1; + } } @override void initState() { super.initState(); - if (PlatformUtils().isWeb) { + if (PlatformUtils().isWeb || PlatformUtils().isDesktop) { focusNode = FocusNode( onKey: (node, event) { - if (event.isKeyPressed(LogicalKeyboardKey.enter)) { - return KeyEventResult.handled; + final activeIndex = widget.model.activeAtIndex; + final showMemberList = widget.model.showAtMemberList; + if (event.runtimeType == RawKeyDownEvent) { + if (event.physicalKey == PhysicalKeyboardKey.backspace) { + if (textEditingController.text.isEmpty && lastText.isEmpty) { + widget.model.repliedMessage = null; + return KeyEventResult.handled; + } + } else if ((event.isShiftPressed || + event.isAltPressed || + event.isControlPressed || + event.isMetaPressed) && + event.physicalKey == PhysicalKeyboardKey.enter) { + final offset = textEditingController.selection.baseOffset; + textEditingController.text = + '${lastText.substring(0, offset)}\n${lastText.substring(offset)}'; + textEditingController.selection = + TextSelection.fromPosition(TextPosition(offset: offset + 1)); + lastText = textEditingController.text; + + return KeyEventResult.handled; + } else if (event.physicalKey == PhysicalKeyboardKey.enter) { + if (!isAddingAtSearchWords || + widget.model.showAtMemberList.isEmpty) { + onSubmitted(); + } else { + isAddingAtSearchWords = false; + final V2TimGroupMemberFullInfo? memberInfo = + showMemberList[activeIndex]; + if (memberInfo != null) { + handleAtMember( + memberInfo: memberInfo, isAddToCursorPosition: true); + } + } + return KeyEventResult.handled; + } + + if (event.isKeyPressed(LogicalKeyboardKey.arrowUp) && + isAddingAtSearchWords && + showMemberList.isNotEmpty) { + final newIndex = max(activeIndex - 1, 0); + widget.model.activeAtIndex = newIndex; + widget.atMemberPanelScroll?.scrollToIndex(newIndex, + preferPosition: AutoScrollPosition.middle); + return KeyEventResult.handled; + } + + if (event.isKeyPressed(LogicalKeyboardKey.arrowDown) && + isAddingAtSearchWords && + showMemberList.isNotEmpty) { + final newIndex = min(activeIndex + 1, showMemberList.length - 1); + widget.model.activeAtIndex = newIndex; + widget.atMemberPanelScroll?.scrollToIndex(newIndex, + preferPosition: AutoScrollPosition.middle); + return KeyEventResult.handled; + } } + return KeyEventResult.ignored; }, ); @@ -620,9 +629,6 @@ class _InputTextFieldState extends TIMUIKitState { if (widget.controller != null) { widget.controller?.addListener(() { final actionType = widget.controller?.actionType; - if (actionType == ActionType.hideAllPanel) { - _hideAllPanel(); - } if (actionType == ActionType.longPressToAt) { _longPressToAt( widget.controller?.atUserID, widget.controller?.atUserName); @@ -633,13 +639,26 @@ class _InputTextFieldState extends TIMUIKitState { if (widget.initText != null) { textEditingController.text = widget.initText!; } - final AppLocale appLocale = I18nUtils.findDeviceLocale(); + final AppLocale appLocale = I18nUtils.findDeviceLocale(null); languageType = (appLocale == AppLocale.zhHans || appLocale == AppLocale.zhHant) ? 'zh' : 'en'; } + @override + void didUpdateWidget(TIMUIKitInputTextField oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.conversationID != oldWidget.conversationID) { + handleSetDraftText(oldWidget.conversationID, oldWidget.conversationType); + if (oldWidget.initText != widget.initText) { + textEditingController.text = widget.initText ?? ""; + } else { + textEditingController.clear(); + } + } + } + @override void dispose() { handleSetDraftText(); @@ -663,6 +682,9 @@ class _InputTextFieldState extends TIMUIKitState { } _getMuteType(TUIChatSeparateViewModel model) async { + if (!mounted) { + return; + } if (widget.conversationType == ConvType.group) { if ((model.groupInfo?.isAllMuted ?? false) && muteStatus != MuteStatus.all) { @@ -689,6 +711,12 @@ class _InputTextFieldState extends TIMUIKitState { }); }); } + } else { + Future.delayed(const Duration(seconds: 0), () { + setState(() { + muteStatus = MuteStatus.none; + }); + }); } } @@ -710,45 +738,11 @@ class _InputTextFieldState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { - final theme = value.theme; final TUIChatSeparateViewModel model = Provider.of(context); - setKeyboardHeight ??= OptimizeUtils.debounce((height) { - settingModel.keyboardHeight = height; - }, const Duration(seconds: 1)); - _getMuteType(model); - final debounceFunc = _debounce((value) { - if (isWebDevice() || isAndroidDevice()) { - if (value.isEmpty && showMoreButton != true) { - setState(() { - showMoreButton = true; - }); - } else if (value.isNotEmpty && showMoreButton == true) { - setState(() { - showMoreButton = false; - }); - } - } - if (widget.onChanged != null) { - widget.onChanged!(value); - } - _handleAtText(value, model); - _handleSendEditStatus(value, true); - final isEmpty = value.isEmpty; - if (isEmpty) { - _handleSoftKeyBoardDelete(); - } - }, const Duration(milliseconds: 80)); - - final MediaQueryData data = MediaQuery.of(context); - EdgeInsets padding = data.padding; - if (bottomPadding == null || padding.bottom > bottomPadding!) { - bottomPadding = padding.bottom; - } - return Selector( builder: ((context, value, child) { String? getForbiddenText() { @@ -765,208 +759,80 @@ class _InputTextFieldState extends TIMUIKitState { } final forbiddenText = getForbiddenText(); - return Column( - children: [ - _buildRepliedMessage(value), - Container( - color: widget.backgroundColor ?? hexToColor("f5f5f6"), - child: Column( - children: [ - Container( - padding: const EdgeInsets.symmetric( - vertical: 8, horizontal: 16), - constraints: const BoxConstraints(minHeight: 50), - child: Row( - children: [ - if (forbiddenText != null) - Expanded( - child: Container( - height: 35, - color: theme.weakBackgroundColor, - alignment: Alignment.center, - child: Text( - TIM_t(forbiddenText), - textAlign: TextAlign.center, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - color: theme.weakTextColor, - ), - ), - )), - if (!PlatformUtils().isWeb && - widget.showSendAudio && - forbiddenText == null) - InkWell( - onTap: () async { - showKeyboard = showSendSoundText; - if (showSendSoundText) { - focusNode.requestFocus(); - } - if (await Permissions.checkPermission( - context, - Permission.microphone.value, - theme, - )) { - setState(() { - showEmojiPanel = false; - showMore = false; - showSendSoundText = !showSendSoundText; - }); - } - }, - child: SvgPicture.asset( - showSendSoundText - ? 'images/keyboard.svg' - : 'images/voice.svg', - package: 'tencent_cloud_chat_uikit', - color: const Color.fromRGBO(68, 68, 68, 1), - height: 28, - width: 28, - ), - ), - if (forbiddenText == null) - const SizedBox( - width: 10, - ), - if (forbiddenText == null) - Expanded( - child: showSendSoundText - ? SendSoundMessage( - onDownBottom: goDownBottom, - conversationID: widget.conversationID, - conversationType: widget.conversationType) - : KeyboardVisibility( - child: ExtendedTextField( - maxLines: 4, - minLines: 1, - focusNode: focusNode, - onChanged: debounceFunc, - onTap: () { - showKeyboard = true; - goDownBottom(); - setState(() { - showEmojiPanel = false; - showMore = false; - }); - }, - keyboardType: TextInputType.multiline, - textInputAction: - PlatformUtils().isAndroid - ? TextInputAction.newline - : TextInputAction.send, - onEditingComplete: onSubmitted, - textAlignVertical: - TextAlignVertical.top, - decoration: InputDecoration( - border: InputBorder.none, - hintStyle: const TextStyle( - // fontSize: 10, - color: Color(0xffAEA4A3), - ), - fillColor: Colors.white, - filled: true, - isDense: true, - hintText: widget.hintText ?? ''), - controller: textEditingController, - specialTextSpanBuilder: PlatformUtils() - .isWeb - ? null - : DefaultSpecialTextSpanBuilder( - isUseDefaultEmoji: - widget.isUseDefaultEmoji, - customEmojiStickerList: widget - .customEmojiStickerList, - showAtBackground: true, - )), - onChanged: (bool visibility) { - if (showKeyboard != visibility) { - setState(() { - showKeyboard = visibility; - }); - } - }), - ), - if (forbiddenText == null) - const SizedBox( - width: 10, - ), - if (widget.showSendEmoji && forbiddenText == null) - InkWell( - onTap: () { - _openEmojiPanel(); - goDownBottom(); - }, - child: PlatformUtils().isWeb - ? Icon( - showEmojiPanel - ? Icons.keyboard_alt_outlined - : Icons.mood_outlined, - color: hexToColor("5c6168"), - size: 32) - : SvgPicture.asset( - showEmojiPanel - ? 'images/keyboard.svg' - : 'images/face.svg', - package: 'tencent_cloud_chat_uikit', - color: - const Color.fromRGBO(68, 68, 68, 1), - height: 28, - width: 28, - ), - ), - if (forbiddenText == null) - const SizedBox( - width: 10, - ), - if (widget.showMorePanel && - forbiddenText == null && - showMoreButton) - InkWell( - onTap: () { - // model.sendCustomMessage(data: "a", convID: model.currentSelectedConv, convType: model.currentSelectedConvType == 1 ? ConvType.c2c : ConvType.group); - _openMore(); - goDownBottom(); - }, - child: PlatformUtils().isWeb - ? Icon(Icons.add_circle_outline_outlined, - color: hexToColor("5c6168"), size: 32) - : SvgPicture.asset( - 'images/add.svg', - package: 'tencent_cloud_chat_uikit', - color: - const Color.fromRGBO(68, 68, 68, 1), - height: 28, - width: 28, - ), - ), - if ((isAndroidDevice() || isWebDevice()) && - !showMoreButton) - SizedBox( - height: 32.0, - child: ElevatedButton( - onPressed: onSubmitted, - child: Text(TIM_t("发送")), - ), - ), - ], - ), - ), - AnimatedContainer( - duration: Duration( - milliseconds: - (showKeyboard && PlatformUtils().isAndroid) - ? 200 - : 340), - curve: Curves.fastOutSlowIn, - height: max(_getBottomHeight(), 0.0), - child: _getBottomContainer(), - ), - ], - ), - ) - ], - ); + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + inputWidth = constraints.maxWidth; + return TUIKitScreenUtils.getDeviceWidget( + defaultWidget: TIMUIKitTextFieldLayoutNarrow( + onEmojiSubmitted: onEmojiSubmitted, + onCustomEmojiFaceSubmitted: onCustomEmojiFaceSubmitted, + backSpaceText: backSpaceText, + addStickerToText: addStickerToText, + customStickerPanel: widget.customStickerPanel, + forbiddenText: forbiddenText, + onChanged: widget.onChanged, + backgroundColor: widget.backgroundColor, + morePanelConfig: widget.morePanelConfig, + repliedMessage: value, + currentCursor: currentCursor, + hintText: widget.hintText, + isUseDefaultEmoji: widget.isUseDefaultEmoji, + languageType: languageType, + textEditingController: textEditingController, + conversationID: widget.conversationID, + conversationType: widget.conversationType, + focusNode: focusNode, + controller: widget.controller, + setCurrentCursor: setCurrentCursor, + onCursorChange: _onCursorChange, + model: model, + handleSendEditStatus: _handleSendEditStatus, + handleAtText: (text) { + _handleAtText(text, model); + }, + handleSoftKeyBoardDelete: _handleSoftKeyBoardDelete, + onSubmitted: onSubmitted, + goDownBottom: goDownBottom, + showSendAudio: widget.showSendAudio, + showSendEmoji: widget.showSendEmoji, + showMorePanel: widget.showMorePanel, + customEmojiStickerList: widget.customEmojiStickerList), + desktopWidget: TIMUIKitTextFieldLayoutWide( + currentConversation: widget.currentConversation, + onEmojiSubmitted: onEmojiSubmitted, + onCustomEmojiFaceSubmitted: onCustomEmojiFaceSubmitted, + backSpaceText: backSpaceText, + addStickerToText: addStickerToText, + customStickerPanel: widget.customStickerPanel, + forbiddenText: forbiddenText, + onChanged: widget.onChanged, + backgroundColor: widget.backgroundColor, + morePanelConfig: widget.morePanelConfig, + repliedMessage: value, + currentCursor: currentCursor, + hintText: widget.hintText, + isUseDefaultEmoji: widget.isUseDefaultEmoji, + languageType: languageType, + textEditingController: textEditingController, + conversationID: widget.conversationID, + conversationType: widget.conversationType, + focusNode: focusNode, + controller: widget.controller, + setCurrentCursor: setCurrentCursor, + onCursorChange: _onCursorChange, + model: model, + handleSendEditStatus: _handleSendEditStatus, + handleAtText: (text) { + _handleAtText(text, model); + }, + handleSoftKeyBoardDelete: _handleSoftKeyBoardDelete, + onSubmitted: onSubmitted, + goDownBottom: goDownBottom, + showSendAudio: widget.showSendAudio, + showSendEmoji: widget.showSendEmoji, + showMorePanel: widget.showMorePanel, + customEmojiStickerList: widget.customEmojiStickerList)); + }); }), selector: (c, model) => model.repliedMessage); } diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart new file mode 100644 index 0000000..40679d4 --- /dev/null +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow.dart @@ -0,0 +1,611 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message.dart'; +import 'package:tencent_extended_text_field/extended_text_field.dart'; +import 'package:tencent_keyboard_visibility/tencent_keyboard_visibility.dart'; + +GlobalKey<_TIMUIKitTextFieldLayoutNarrowState> narrowTextFieldKey = GlobalKey(); + +class TIMUIKitTextFieldLayoutNarrow extends StatefulWidget { + /// sticker panel customization + final CustomStickerPanel? customStickerPanel; + + final VoidCallback onEmojiSubmitted; + final Function(int, String) onCustomEmojiFaceSubmitted; + final Function(String, bool) handleSendEditStatus; + final VoidCallback backSpaceText; + final ValueChanged addStickerToText; + + final ValueChanged handleAtText; + + /// Whether to use the default emoji + final bool isUseDefaultEmoji; + + final TUIChatSeparateViewModel model; + + /// background color + final Color? backgroundColor; + + /// control input field behavior + final TIMUIKitInputTextFieldController? controller; + + /// config for more panel + final MorePanelConfig? morePanelConfig; + + final String languageType; + + final TextEditingController textEditingController; + + /// conversation id + final String conversationID; + + /// conversation type + final ConvType conversationType; + + final FocusNode focusNode; + + /// show more panel + final bool showMorePanel; + + /// hint text for textField widget + final String? hintText; + + final int? currentCursor; + + final ValueChanged setCurrentCursor; + + final VoidCallback onCursorChange; + + /// show send audio icon + final bool showSendAudio; + + final VoidCallback handleSoftKeyBoardDelete; + + /// on text changed + final void Function(String)? onChanged; + + final V2TimMessage? repliedMessage; + + /// show send emoji icon + final bool showSendEmoji; + + final String? forbiddenText; + + final VoidCallback onSubmitted; + + final VoidCallback goDownBottom; + + final List customEmojiStickerList; + + const TIMUIKitTextFieldLayoutNarrow( + {Key? key, + this.customStickerPanel, + required this.onEmojiSubmitted, + required this.onCustomEmojiFaceSubmitted, + required this.backSpaceText, + required this.addStickerToText, + required this.isUseDefaultEmoji, + required this.languageType, + required this.textEditingController, + this.morePanelConfig, + required this.conversationID, + required this.conversationType, + required this.focusNode, + this.currentCursor, + required this.setCurrentCursor, + required this.onCursorChange, + required this.model, + this.backgroundColor, + this.onChanged, + required this.handleSendEditStatus, + required this.handleAtText, + required this.handleSoftKeyBoardDelete, + this.repliedMessage, + this.forbiddenText, + required this.onSubmitted, + required this.goDownBottom, + required this.showSendAudio, + required this.showSendEmoji, + required this.showMorePanel, + this.hintText, + required this.customEmojiStickerList, + this.controller}) + : super(key: key); + + @override + State createState() => + _TIMUIKitTextFieldLayoutNarrowState(); +} + +class _TIMUIKitTextFieldLayoutNarrowState + extends TIMUIKitState { + final TUISettingModel settingModel = serviceLocator(); + + bool showMore = false; + bool showMoreButton = true; + bool showSendSoundText = false; + bool showEmojiPanel = false; + bool showKeyboard = false; + Function? setKeyboardHeight; + double? bottomPadding; + + @override + void initState() { + super.initState(); + if (widget.controller != null) { + widget.controller?.addListener(() { + final actionType = widget.controller?.actionType; + if (actionType == ActionType.hideAllPanel) { + hideAllPanel(); + } + }); + } + } + + void setSendButton() { + final value = widget.textEditingController.text; + if (isWebDevice() || isAndroidDevice()) { + if (value.isEmpty && showMoreButton != true) { + setState(() { + showMoreButton = true; + }); + } else if (value.isNotEmpty && showMoreButton == true) { + setState(() { + showMoreButton = false; + }); + } + } + } + + hideAllPanel() { + widget.focusNode.unfocus(); + widget.currentCursor == null; + if (showKeyboard != false || showMore != false || showEmojiPanel != false) { + setState(() { + showKeyboard = false; + showMore = false; + showEmojiPanel = false; + }); + } + } + + Widget _getBottomContainer() { + if (showEmojiPanel) { + return widget.customStickerPanel != null + ? widget.customStickerPanel!( + sendTextMessage: () { + widget.onEmojiSubmitted(); + setSendButton(); + }, + sendFaceMessage: widget.onCustomEmojiFaceSubmitted, + deleteText: () { + widget.backSpaceText(); + setSendButton(); + }, + addText: (int unicode) { + final newText = String.fromCharCode(unicode); + widget.addStickerToText(newText); + // handleSetDraftText(); + }, + addCustomEmojiText: ((String singleEmojiName) { + String? emojiName = singleEmojiName.split('.png')[0]; + if (widget.isUseDefaultEmoji && + widget.languageType == 'zh' && + ConstData.emojiMapList[emojiName] != null && + ConstData.emojiMapList[emojiName] != '') { + emojiName = ConstData.emojiMapList[emojiName]; + } + final newText = '[$emojiName]'; + widget.addStickerToText(newText); + setSendButton(); + }), + defaultCustomEmojiStickerList: + widget.isUseDefaultEmoji ? ConstData.emojiList : []) + : EmojiPanel(onTapEmoji: (unicode) { + final newText = String.fromCharCode(unicode); + widget.addStickerToText(newText); + setSendButton(); + // handleSetDraftText(); + }, onSubmitted: () { + widget.onEmojiSubmitted(); + setSendButton(); + }, delete: () { + widget.backSpaceText(); + setSendButton(); + }); + } + + if (showMore) { + return MorePanel( + morePanelConfig: widget.morePanelConfig, + conversationID: widget.conversationID, + conversationType: widget.conversationType); + } + + return const SizedBox(height: 0); + } + + double _getBottomHeight() { + if (showKeyboard) { + final currentKeyboardHeight = MediaQuery.of(context).viewInsets.bottom; + double originHeight = settingModel.keyboardHeight; + if (currentKeyboardHeight != 0) { + if (currentKeyboardHeight >= originHeight) { + originHeight = currentKeyboardHeight; + } + if (setKeyboardHeight != null) { + setKeyboardHeight!(currentKeyboardHeight); + } + } + final height = originHeight != 0 ? originHeight : currentKeyboardHeight; + return height; + } else if (showMore || showEmojiPanel) { + return 248.0 + (bottomPadding ?? 0.0); + } else if (widget.textEditingController.text.length >= 46 && + showKeyboard == false) { + return 25 + (bottomPadding ?? 0.0); + } else { + return bottomPadding ?? 0; + } + } + + _openMore() { + if (!showMore) { + widget.focusNode.unfocus(); + widget.setCurrentCursor(null); + } + setState(() { + showKeyboard = false; + showEmojiPanel = false; + showSendSoundText = false; + showMore = !showMore; + }); + } + + _openEmojiPanel() { + widget.onCursorChange(); + showKeyboard = showEmojiPanel; + if (showEmojiPanel) { + widget.focusNode.requestFocus(); + } else { + widget.focusNode.unfocus(); + } + + setState(() { + showMore = false; + showSendSoundText = false; + showEmojiPanel = !showEmojiPanel; + }); + } + + _debounce( + Function(String text) fun, [ + Duration delay = const Duration(milliseconds: 30), + ]) { + Timer? timer; + return (String text) { + if (timer != null) { + timer?.cancel(); + } + + timer = Timer(delay, () { + fun(text); + }); + }; + } + + _buildRepliedMessage(V2TimMessage? repliedMessage) { + final haveRepliedMessage = repliedMessage != null; + if (haveRepliedMessage) { + final text = + "${MessageUtils.getDisplayName(widget.model.repliedMessage!)}:${widget.model.abstractMessageBuilder != null ? widget.model.abstractMessageBuilder!(widget.model.repliedMessage!) : MessageUtils.getAbstractMessageAsync(widget.model.repliedMessage!, widget.model.groupMemberList ?? [])}"; + return Container( + color: widget.backgroundColor ?? hexToColor("f5f5f6"), + alignment: Alignment.centerLeft, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + text, + softWrap: true, + maxLines: 3, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: hexToColor("8f959e"), fontSize: 14), + ), + ), + const SizedBox( + width: 16, + ), + InkWell( + onTap: () { + widget.model.repliedMessage = null; + }, + child: Icon(Icons.clear, color: hexToColor("8f959e"), size: 18), + ) + ], + ), + ); + } + return Container(); + } + + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; + + setKeyboardHeight ??= OptimizeUtils.debounce((height) { + settingModel.keyboardHeight = height; + }, const Duration(seconds: 1)); + + final debounceFunc = _debounce((value) { + if (isWebDevice() || isAndroidDevice()) { + if (value.isEmpty && showMoreButton != true) { + setState(() { + showMoreButton = true; + }); + } else if (value.isNotEmpty && showMoreButton == true) { + setState(() { + showMoreButton = false; + }); + } + } + if (widget.onChanged != null) { + widget.onChanged!(value); + } + widget.handleAtText(value); + widget.handleSendEditStatus(value, true); + final isEmpty = value.isEmpty; + if (isEmpty) { + widget.handleSoftKeyBoardDelete(); + } + }, const Duration(milliseconds: 80)); + + final MediaQueryData data = MediaQuery.of(context); + EdgeInsets padding = data.padding; + if (bottomPadding == null || padding.bottom > bottomPadding!) { + bottomPadding = padding.bottom; + } + + return Column( + children: [ + _buildRepliedMessage(widget.repliedMessage), + Container( + color: widget.backgroundColor ?? hexToColor("f5f5f6"), + child: Column( + children: [ + Container( + padding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + constraints: const BoxConstraints(minHeight: 50), + child: Row( + children: [ + if (widget.forbiddenText != null) + Expanded( + child: Container( + height: 35, + color: theme.weakBackgroundColor, + alignment: Alignment.center, + child: Text( + TIM_t(widget.forbiddenText!), + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + color: theme.weakTextColor, + ), + ), + )), + if (PlatformUtils().isMobile && + widget.showSendAudio && + widget.forbiddenText == null) + InkWell( + onTap: () async { + showKeyboard = showSendSoundText; + if (showSendSoundText) { + widget.focusNode.requestFocus(); + } + if (await Permissions.checkPermission( + context, + Permission.microphone.value, + theme, + )) { + setState(() { + showEmojiPanel = false; + showMore = false; + showSendSoundText = !showSendSoundText; + }); + } + }, + child: SvgPicture.asset( + showSendSoundText + ? 'images/keyboard.svg' + : 'images/voice.svg', + package: 'tencent_cloud_chat_uikit', + color: const Color.fromRGBO(68, 68, 68, 1), + height: 28, + width: 28, + ), + ), + if (widget.forbiddenText == null) + const SizedBox( + width: 10, + ), + if (widget.forbiddenText == null) + Expanded( + child: showSendSoundText + ? SendSoundMessage( + onDownBottom: widget.goDownBottom, + conversationID: widget.conversationID, + conversationType: widget.conversationType) + : KeyboardVisibility( + child: ExtendedTextField( + maxLines: 4, + minLines: 1, + focusNode: widget.focusNode, + onChanged: debounceFunc, + onTap: () { + showKeyboard = true; + widget.goDownBottom(); + setState(() { + showEmojiPanel = false; + showMore = false; + }); + }, + keyboardType: TextInputType.multiline, + textInputAction: PlatformUtils().isAndroid + ? TextInputAction.newline + : TextInputAction.send, + onEditingComplete: () { + widget.onSubmitted(); + if (showKeyboard) { + widget.focusNode.requestFocus(); + } + setState(() { + if (widget.textEditingController.text + .isEmpty) { + showMoreButton = true; + } + }); + }, + textAlignVertical: TextAlignVertical.top, + decoration: InputDecoration( + border: InputBorder.none, + hintStyle: const TextStyle( + // fontSize: 10, + color: Color(0xffAEA4A3), + ), + fillColor: Colors.white, + filled: true, + isDense: true, + hintText: widget.hintText ?? ''), + controller: widget.textEditingController, + specialTextSpanBuilder: PlatformUtils() + .isWeb + ? null + : DefaultSpecialTextSpanBuilder( + isUseDefaultEmoji: + widget.isUseDefaultEmoji, + customEmojiStickerList: + widget.customEmojiStickerList, + showAtBackground: true, + )), + onChanged: (bool visibility) { + if (showKeyboard != visibility) { + setState(() { + showKeyboard = visibility; + }); + } + }), + ), + if (widget.forbiddenText == null) + const SizedBox( + width: 10, + ), + if (widget.showSendEmoji && widget.forbiddenText == null) + InkWell( + onTap: () { + _openEmojiPanel(); + widget.goDownBottom(); + }, + child: PlatformUtils().isWeb + ? Icon( + showEmojiPanel + ? Icons.keyboard_alt_outlined + : Icons.mood_outlined, + color: hexToColor("5c6168"), + size: 32) + : SvgPicture.asset( + showEmojiPanel + ? 'images/keyboard.svg' + : 'images/face.svg', + package: 'tencent_cloud_chat_uikit', + color: const Color.fromRGBO(68, 68, 68, 1), + height: 28, + width: 28, + ), + ), + if (widget.forbiddenText == null) + const SizedBox( + width: 10, + ), + if (widget.showMorePanel && + widget.forbiddenText == null && + showMoreButton) + InkWell( + onTap: () { + // model.sendCustomMessage(data: "a", convID: model.currentSelectedConv, convType: model.currentSelectedConvType == 1 ? ConvType.c2c : ConvType.group); + _openMore(); + widget.goDownBottom(); + }, + child: PlatformUtils().isWeb + ? Icon(Icons.add_circle_outline_outlined, + color: hexToColor("5c6168"), size: 32) + : SvgPicture.asset( + 'images/add.svg', + package: 'tencent_cloud_chat_uikit', + color: const Color.fromRGBO(68, 68, 68, 1), + height: 28, + width: 28, + ), + ), + if ((isAndroidDevice() || isWebDevice()) && !showMoreButton) + SizedBox( + height: 32.0, + child: ElevatedButton( + onPressed: () { + widget.onSubmitted(); + if (showKeyboard) { + widget.focusNode.requestFocus(); + } + setState(() { + if (widget.textEditingController.text.isEmpty) { + showMoreButton = true; + } + }); + }, + child: Text(TIM_t("发送")), + ), + ), + ], + ), + ), + AnimatedContainer( + duration: Duration( + milliseconds: (showKeyboard && PlatformUtils().isAndroid) + ? 200 + : 340), + curve: Curves.fastOutSlowIn, + height: max(_getBottomHeight(), 0.0), + child: ListView( + physics: const NeverScrollableScrollPhysics(), + children: [ + _getBottomContainer() + ], + ), + ), + ], + ), + ) + ], + ); + } +} diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart new file mode 100644 index 0000000..ef8f10d --- /dev/null +++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart @@ -0,0 +1,963 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:math'; +import 'package:fc_native_video_thumbnail_for_us/fc_native_video_thumbnail_for_us.dart'; +import 'package:flutter/services.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:pasteboard/pasteboard.dart'; +import 'package:path/path.dart' as p; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_setting_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_shot.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/drag_widget.dart'; +import 'package:tencent_extended_text_field/extended_text_field.dart'; +import 'package:universal_html/html.dart' as html; +import 'package:url_launcher/url_launcher.dart'; +import 'package:uuid/uuid.dart'; +import 'package:wechat_assets_picker/wechat_assets_picker.dart'; + +// ignore: unnecessary_import +import 'dart:typed_data'; + +class DesktopControlBarItem { + final String item; + final IconData? icon; + final String? imgPath; + final Color? color; + final ValueChanged onClick; + final String? showName; + final double? size; + + DesktopControlBarItem( + {required this.item, + this.icon, + this.color, + this.imgPath, + required this.onClick, + this.showName, + this.size}) + : assert(icon != null || imgPath != null); +} + +class DesktopControlBarConfig { + final bool showStickerPanel; + final bool showScreenshotButton; + final bool showSendFileButton; + final bool showSendImageButton; + final bool showSendVideoButton; + final bool showMessageHistoryButton; + + DesktopControlBarConfig({ + this.showStickerPanel = true, + this.showScreenshotButton = true, + this.showSendFileButton = true, + this.showSendImageButton = true, + this.showSendVideoButton = true, + this.showMessageHistoryButton = true, + }); +} + +class TIMUIKitTextFieldLayoutWide extends StatefulWidget { + /// sticker panel customization + final CustomStickerPanel? customStickerPanel; + final VoidCallback onEmojiSubmitted; + final Function(int, String) onCustomEmojiFaceSubmitted; + final Function(String, bool) handleSendEditStatus; + final VoidCallback backSpaceText; + final ValueChanged addStickerToText; + + final ValueChanged handleAtText; + + /// Whether to use the default emoji + final bool isUseDefaultEmoji; + + final TUIChatSeparateViewModel model; + + /// background color + final Color? backgroundColor; + + /// control input field behavior + final TIMUIKitInputTextFieldController? controller; + + /// config for more panel + final MorePanelConfig? morePanelConfig; + + final String languageType; + + final TextEditingController textEditingController; + + /// conversation id + final String conversationID; + + /// conversation type + final ConvType conversationType; + + final FocusNode focusNode; + + /// show more panel + final bool showMorePanel; + + /// hint text for textField widget + final String? hintText; + + final int? currentCursor; + + final ValueChanged setCurrentCursor; + + final VoidCallback onCursorChange; + + /// show send audio icon + final bool showSendAudio; + + final VoidCallback handleSoftKeyBoardDelete; + + /// on text changed + final void Function(String)? onChanged; + + final V2TimMessage? repliedMessage; + + /// show send emoji icon + final bool showSendEmoji; + + final String? forbiddenText; + + final VoidCallback onSubmitted; + + final VoidCallback goDownBottom; + + final List customEmojiStickerList; + + /// Conversation need search + final V2TimConversation currentConversation; + + const TIMUIKitTextFieldLayoutWide( + {Key? key, + this.customStickerPanel, + required this.onEmojiSubmitted, + required this.onCustomEmojiFaceSubmitted, + required this.backSpaceText, + required this.addStickerToText, + required this.isUseDefaultEmoji, + required this.languageType, + required this.textEditingController, + this.morePanelConfig, + required this.conversationID, + required this.conversationType, + required this.focusNode, + this.currentCursor, + required this.setCurrentCursor, + required this.onCursorChange, + required this.model, + this.backgroundColor, + this.onChanged, + required this.handleSendEditStatus, + required this.handleAtText, + required this.handleSoftKeyBoardDelete, + this.repliedMessage, + this.forbiddenText, + required this.onSubmitted, + required this.goDownBottom, + required this.showSendAudio, + required this.showSendEmoji, + required this.showMorePanel, + this.hintText, + required this.customEmojiStickerList, + this.controller, + required this.currentConversation}) + : super(key: key); + + @override + State createState() => + _TIMUIKitTextFieldLayoutWideState(); +} + +class _TIMUIKitTextFieldLayoutWideState + extends TIMUIKitState { + final TUISettingModel settingModel = serviceLocator(); + OverlayEntry? entry; + final ImagePicker _picker = ImagePicker(); + Uint8List? fileContent; + String? fileName; + File? tempFile; + Function? setKeyboardHeight; + double? bottomPadding; + late ScrollController _scrollController; + late FocusNode textFocusNode; + + @override + void initState() { + super.initState(); + if (widget.controller != null) { + widget.controller?.addListener(() { + final actionType = widget.controller?.actionType; + if (actionType == ActionType.hideAllPanel) { + hideAllPanel(); + } + }); + } + textFocusNode = FocusNode(); + widget.focusNode.requestFocus(); + _scrollController = ScrollController(); + } + + hideAllPanel() { + widget.focusNode.unfocus(); + widget.currentCursor == null; + } + + _debounce( + Function(String text) fun, [ + Duration delay = const Duration(milliseconds: 30), + ]) { + Timer? timer; + return (String text) { + if (timer != null) { + timer?.cancel(); + } + + timer = Timer(delay, () { + fun(text); + }); + }; + } + + _buildRepliedMessage(V2TimMessage? repliedMessage) { + final haveRepliedMessage = repliedMessage != null; + if (haveRepliedMessage) { + final text = + "${MessageUtils.getDisplayName(widget.model.repliedMessage!)}:${widget.model.abstractMessageBuilder != null ? widget.model.abstractMessageBuilder!(widget.model.repliedMessage!) : MessageUtils.getAbstractMessageAsync(widget.model.repliedMessage!, widget.model.groupMemberList ?? [])}"; + return Container( + color: widget.backgroundColor ?? hexToColor("f5f5f6"), + alignment: Alignment.centerLeft, + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + text, + softWrap: true, + maxLines: 3, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: hexToColor("8f959e"), fontSize: 14), + ), + ), + const SizedBox( + width: 16, + ), + InkWell( + onTap: () { + widget.model.repliedMessage = null; + }, + child: Icon(Icons.clear, color: hexToColor("8f959e"), size: 18), + ) + ], + ), + ); + } + return Container(); + } + + _sendEmoji(Offset? offset, TUITheme theme) { + widget.onCursorChange(); + if (entry != null) { + entry?.remove(); + entry = null; + } else { + entry = OverlayEntry(builder: (BuildContext context) { + return TUIKitDragArea( + closeFun: () { + if (entry != null) { + entry?.remove(); + entry = null; + } + }, + initOffset: offset ?? + Offset(MediaQuery.of(context).size.height * 0.5 + 20, + MediaQuery.of(context).size.height * 0.5 - 100), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(8)), + color: theme.wideBackgroundColor, + border: Border.all( + width: 2, + color: theme.weakBackgroundColor ?? const Color(0xFFbebebe), + ), + boxShadow: const [ + BoxShadow( + color: Color(0xFFbebebe), + offset: Offset(5, 5), + blurRadius: 10, + spreadRadius: 1, + ), + ], + ), + child: Container( + child: widget.customStickerPanel != null + ? widget.customStickerPanel!( + height: 400, + width: 350, + sendTextMessage: () { + widget.onEmojiSubmitted(); + }, + sendFaceMessage: widget.onCustomEmojiFaceSubmitted, + deleteText: () { + widget.backSpaceText(); + }, + addText: (int unicode) { + final newText = String.fromCharCode(unicode); + widget.addStickerToText(newText); + }, + addCustomEmojiText: ((String singleEmojiName) { + String? emojiName = singleEmojiName.split('.png')[0]; + if (widget.isUseDefaultEmoji && + widget.languageType == 'zh' && + ConstData.emojiMapList[emojiName] != null && + ConstData.emojiMapList[emojiName] != '') { + emojiName = ConstData.emojiMapList[emojiName]; + } + final newText = '[$emojiName]'; + widget.addStickerToText(newText); + }), + defaultCustomEmojiStickerList: + widget.isUseDefaultEmoji ? ConstData.emojiList : []) + : EmojiPanel(onTapEmoji: (unicode) { + final newText = String.fromCharCode(unicode); + widget.addStickerToText(newText); + }, onSubmitted: () { + widget.onEmojiSubmitted(); + }, delete: () { + widget.backSpaceText(); + }), + ), + )); + }); + Overlay.of(context)?.insert(entry!); + } + } + + _addGreyOverlay() { + if (entry != null) { + _removeOverlay(); + return; + } else { + entry = OverlayEntry(builder: (BuildContext context) { + return Container( + color: const Color(0x7F000000), + ); + }); + Overlay.of(context)?.insert(entry!); + } + } + + _removeOverlay() { + entry!.remove(); + entry = null; + } + + _sendFile( + TUIChatSeparateViewModel model, + TUITheme theme, + ) async { + if (!PlatformUtils().isWeb) { + _addGreyOverlay(); + } + try { + final convID = widget.conversationID; + final convType = widget.conversationType; + FilePickerResult? result = await FilePicker.platform.pickFiles(); + _removeOverlay(); + if (result != null && result.files.isNotEmpty) { + if (PlatformUtils().isWeb) { + html.Node? inputElem; + inputElem = html.document + .getElementById("__file_picker_web-file-input") + ?.querySelector("input"); + fileName = result.files.single.name; + + MessageUtils.handleMessageError( + model.sendFileMessage( + inputElement: inputElem, + fileName: fileName, + convID: convID, + convType: convType), + context); + return; + } + + File file = File(result.files.single.path!); + final int size = file.lengthSync(); + final String savePath = file.path; + + MessageUtils.handleMessageError( + model.sendFileMessage( + filePath: savePath, + size: size, + convID: convID, + convType: convType), + context); + } else { + throw TypeError(); + } + } catch (e) { + // ignore: avoid_print + print("_sendFileErr: ${e.toString()}"); + } + } + + List generateBarIcons( + List items, TUITheme theme) { + return items.map((e) { + final GlobalKey key = GlobalKey(); + return Container( + margin: const EdgeInsets.only(right: 6), + child: InkWell( + onTap: () { + final alignBox = + key.currentContext?.findRenderObject() as RenderBox?; + var offset = alignBox?.localToGlobal(Offset.zero); + final double? dx = (offset?.dx != null) ? offset!.dx : null; + final double? dy = + (offset?.dy != null && alignBox?.size.height != null) + ? offset!.dy - 420 + : null; + e.onClick((dx != null && dy != null) ? Offset(dx, dy) : null); + }, + child: Tooltip( + preferBelow: false, + textStyle: TextStyle(fontSize: 12, color: theme.white), + message: e.showName, + child: Container( + decoration: + BoxDecoration(borderRadius: BorderRadius.circular(2)), + padding: const EdgeInsets.all(4), + child: e.imgPath != null + ? Image.asset( + e.imgPath!, + key: key, + width: e.size ?? 20, + height: e.size ?? 20, + ) + : Icon(e.icon, + key: key, + color: e.color ?? hexToColor("646a73"), + size: e.size ?? 20)), + ), + ), + ); + }).toList(); + } + + _sendImageFileOnWeb(TUIChatSeparateViewModel model) async { + try { + final pickedFile = await _picker.pickImage(source: ImageSource.gallery); + final imageContent = await pickedFile!.readAsBytes(); + fileName = pickedFile.name; + tempFile = File(pickedFile.path); + fileContent = imageContent; + + html.Node? inputElem; + inputElem = html.document + .getElementById("__image_picker_web-file-input") + ?.querySelector("input"); + final convID = widget.conversationID; + final convType = widget.conversationType; + MessageUtils.handleMessageError( + model.sendImageMessage( + inputElement: inputElem, + imagePath: tempFile?.path, + convID: convID, + convType: convType), + context); + } catch (e) { + // ignore: avoid_print + print("_sendFileErr: ${e.toString()}"); + } + } + + _sendVideoFileOnWeb(TUIChatSeparateViewModel model) async { + try { + final pickedFile = await _picker.pickVideo(source: ImageSource.gallery); + final videoContent = await pickedFile!.readAsBytes(); + fileName = pickedFile.name; + tempFile = File(pickedFile.path); + fileContent = videoContent; + + if (fileName!.split(".")[fileName!.split(".").length - 1] != "mp4") { + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("视频消息仅限 mp4 格式"), + infoCode: 6660412)); + return; + } + + html.Node? inputElem; + inputElem = html.document + .getElementById("__image_picker_web-file-input") + ?.querySelector("input"); + final convID = widget.conversationID; + final convType = widget.conversationType; + MessageUtils.handleMessageError( + model.sendVideoMessage( + inputElement: inputElem, + videoPath: tempFile?.path, + convID: convID, + convType: convType), + context); + } catch (e) { + // ignore: avoid_print + print("_sendFileErr: ${e.toString()}"); + } + } + + _sendVideoMessage(AssetEntity asset, TUIChatSeparateViewModel model) async { + try { + final plugin = FcNativeVideoThumbnail(); + final originFile = await asset.originFile; + final size = await originFile!.length(); + if (size >= 104857600) { + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("发送失败,视频不能大于100MB"), + infoCode: 6660405)); + return; + } + + final duration = asset.videoDuration.inSeconds; + final filePath = originFile.path; + final convID = widget.conversationID; + final convType = widget.conversationType; + + String tempPath = (await getTemporaryDirectory()).path + + p.extension(originFile.path, 3) + + ".jpeg"; + + await plugin.getVideoThumbnail( + srcFile: originFile.path, + keepAspectRatio: true, + destFile: tempPath, + format: 'jpeg', + width: 128, + quality: 100, + height: 128, + ); + MessageUtils.handleMessageError( + model.sendVideoMessage( + videoPath: filePath, + duration: duration, + snapshotPath: tempPath, + convID: convID, + convType: convType), + context); + } catch (e) { + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("视频文件异常"), + infoCode: 6660415)); + } + } + + _sendMediaMessage( + TUIChatSeparateViewModel model, TUITheme theme, FileType fileType) async { + try { + final convID = widget.conversationID; + final convType = widget.conversationType; + + if (PlatformUtils().isMobile) { + final pickedAssets = await AssetPicker.pickAssets(context); + + if (pickedAssets != null) { + for (var asset in pickedAssets) { + final originFile = await asset.originFile; + final filePath = originFile?.path; + final type = asset.type; + if (filePath != null) { + if (type == AssetType.image) { + MessageUtils.handleMessageError( + model.sendImageMessage( + imagePath: filePath, + convID: convID, + convType: convType), + context); + } + + if (type == AssetType.video) { + _sendVideoMessage(asset, model); + } + } + } + } + } else { + final plugin = FcNativeVideoThumbnail(); + _addGreyOverlay(); + FilePickerResult? result = + await FilePicker.platform.pickFiles(type: fileType); + _removeOverlay(); + if (result != null && result.files.isNotEmpty) { + File file = File(result.files.single.path!); + final String savePath = file.path; + final String type = TencentUtils.getFileType( + (savePath.split(".")[savePath.split(".").length - 1]) + .toLowerCase()) + .split("/")[0]; + + if (type == "image") { + MessageUtils.handleMessageError( + model.sendImageMessage( + imagePath: savePath, convID: convID, convType: convType), + context); + } else if (type == "video") { + String tempPath = (await getTemporaryDirectory()).path + + p.basename(savePath) + + ".jpeg"; + await plugin.getVideoThumbnail( + srcFile: savePath, + keepAspectRatio: true, + destFile: tempPath, + format: 'jpeg', + width: 128, + quality: 100, + height: 128, + ); + MessageUtils.handleMessageError( + model.sendVideoMessage( + videoPath: savePath, + convID: convID, + convType: convType, + snapshotPath: tempPath), + context); + } + } else { + throw TypeError(); + } + } + } catch (err) { + // ignore: avoid_print + print("send media err: $err"); + onTIMCallback(TIMCallback( + type: TIMCallbackType.INFO, + infoRecommendText: TIM_t("视频文件异常"), + infoCode: 6660415)); + } + } + + _sendImageWithConfirmation(String file) async { + final option1 = widget.currentConversation.showName ?? + (widget.conversationType == ConvType.group ? TIM_t("群聊") : TIM_t("对方")); + final size = await ScreenshotHelper.getImageSize(file); + + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.beforeSendScreenShot, + context: context, + isDarkBackground: false, + width: 500, + height: min(500, size.height / 2 + 140), + title: TIM_t_para("发送给{{option1}}", "发送给$option1")(option1: option1), + child: (closeFunc) => Container( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + height: min(360, size.height / 2), + child: InkWell( + onTap: () { + launchUrl(Uri.file(file)); + }, + child: Image.file( + File(file), + height: min(360, size.height / 2), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + OutlinedButton( + onPressed: () { + closeFunc(); + }, + child: Text(TIM_t("取消"))), + const SizedBox( + width: 20, + ), + ElevatedButton( + onPressed: () { + MessageUtils.handleMessageError( + widget.model.sendImageMessage( + imagePath: file, + convID: widget.conversationID, + convType: widget.conversationType), + context); + closeFunc(); + }, + child: Text(TIM_t("发送"))) + ], + ) + ], + ), + )); + } + + _sendScreenShot() async { + final file = await ScreenshotHelper.captureScreen(); + if (file != null) { + _sendImageWithConfirmation(file); + } else {} + } + + List generateControlBar( + TUIChatSeparateViewModel model, TUITheme theme) { + final DesktopControlBarConfig config = + widget.model.chatConfig.desktopControlBarConfig ?? + DesktopControlBarConfig(); + final List itemsList = [ + if (config.showStickerPanel) + DesktopControlBarItem( + item: "face", + showName: TIM_t("表情"), + onClick: (offset) { + _sendEmoji(offset, theme); + }, + icon: Icons.mood), + if (config.showScreenshotButton && PlatformUtils().isDesktop) + DesktopControlBarItem( + item: "screenShot", + showName: TIM_t("截图"), + onClick: (offset) { + _sendScreenShot(); + }, + icon: Icons.cut_outlined), + if (config.showSendFileButton) + DesktopControlBarItem( + item: "file", + showName: TIM_t("文件"), + onClick: (offset) { + _sendFile(widget.model, theme); + }, + icon: Icons.file_copy_outlined), + if (config.showSendImageButton) + DesktopControlBarItem( + item: "photo", + showName: TIM_t("图片"), + onClick: (offset) { + if (PlatformUtils().isWeb) { + _sendImageFileOnWeb(widget.model); + } else { + _sendMediaMessage(widget.model, theme, FileType.image); + } + }, + icon: Icons.image_outlined), + if (config.showSendVideoButton) + DesktopControlBarItem( + item: "video", + showName: TIM_t("视频"), + onClick: (offset) { + if (PlatformUtils().isWeb) { + _sendVideoFileOnWeb(widget.model); + } else { + _sendMediaMessage(widget.model, theme, FileType.video); + } + }, + icon: Icons.video_library_outlined), + if (config.showMessageHistoryButton) + DesktopControlBarItem( + item: "history", + showName: TIM_t("消息历史"), + onClick: (offset) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.chatHistory, + context: context, + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.width * 0.5, + child: (onClose) => TIMUIKitSearchMsgDetail( + currentConversation: widget.currentConversation, + keyword: '', + initMessageList: widget.model + .getOriginMessageList() + .getRange( + 0, + min(widget.model.getOriginMessageList().length, + 100)) + .toList(), + onTapConversation: (V2TimConversation conversation, + V2TimMessage? message) {}, + ), + theme: theme); + }, + icon: Icons.chat_outlined), + ...(widget.model.chatConfig.additionalDesktopControlBarItems ?? []) + ]; + + return generateBarIcons(itemsList, theme); + } + + Future _handleKeyEvent(RawKeyEvent event) async { + if ((event.isKeyPressed(LogicalKeyboardKey.controlLeft) && + event.logicalKey == LogicalKeyboardKey.keyV) || + (event.isMetaPressed && event.logicalKey == LogicalKeyboardKey.keyV)) { + final bytes = await Pasteboard.image; + if (bytes != null) { + String directory; + if (PlatformUtils().isWindows) { + final String documentsDirectoryPath = + "${Platform.environment['USERPROFILE']}"; + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + String pkgName = packageInfo.packageName; + directory = p.join(documentsDirectoryPath, "Documents", + ".TencentCloudChat", pkgName, "screenshots"); + } else { + final dic = await getApplicationSupportDirectory(); + directory = dic.path; + } + const uuid = Uuid(); + final fileName = 'paste_image_${uuid.v4()}.png'; + final scDirectory = Directory(directory); + final filePath = + '${scDirectory.path}${PlatformUtils().isWindows ? "\\" : "/"}$fileName'; + final file = File(filePath); + if (!await scDirectory.exists()) { + await scDirectory.create(recursive: true); + } + await file.writeAsBytes(bytes.toList()); + _sendImageWithConfirmation(filePath); + } + } + } + + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; + + setKeyboardHeight ??= OptimizeUtils.debounce((height) { + settingModel.keyboardHeight = height; + }, const Duration(seconds: 1)); + + final debounceFunc = _debounce((value) { + if (widget.onChanged != null) { + widget.onChanged!(value); + } + widget.handleAtText(value); + widget.handleSendEditStatus(value, true); + final isEmpty = value.isEmpty; + if (isEmpty) { + widget.handleSoftKeyBoardDelete(); + } + }, const Duration(milliseconds: 80)); + + final MediaQueryData data = MediaQuery.of(context); + EdgeInsets padding = data.padding; + if (bottomPadding == null || padding.bottom > bottomPadding!) { + bottomPadding = padding.bottom; + } + + return RawKeyboardListener( + focusNode: textFocusNode, + onKey: _handleKeyEvent, + child: Container( + color: widget.backgroundColor, + child: Column( + children: [ + SizedBox( + height: 1, + child: Container( + color: theme.weakDividerColor ?? Colors.black12)), + if (widget.forbiddenText == null) + Container( + padding: + const EdgeInsets.symmetric(vertical: 4, horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: generateControlBar(widget.model, theme), + ), + ), + _buildRepliedMessage(widget.repliedMessage), + Container( + padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 6), + constraints: const BoxConstraints(minHeight: 50), + child: Row( + children: [ + if (widget.forbiddenText != null) + Expanded( + child: Container( + height: 35, + color: theme.weakBackgroundColor, + alignment: Alignment.center, + child: Text( + TIM_t(widget.forbiddenText!), + textAlign: TextAlign.center, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + color: theme.weakTextColor, + ), + ), + )), + if (widget.forbiddenText == null) + Expanded( + child: Scrollbar( + controller: _scrollController, + child: ExtendedTextField( + autofocus: true, + maxLines: 6, + minLines: 6, + focusNode: widget.focusNode, + onChanged: debounceFunc, + keyboardType: TextInputType.multiline, + textInputAction: PlatformUtils().isAndroid + ? TextInputAction.newline + : TextInputAction.send, + onEditingComplete: () { + widget.onSubmitted(); + }, + textAlignVertical: TextAlignVertical.top, + style: const TextStyle(fontSize: 14), + decoration: InputDecoration( + hoverColor: hexToColor("fafafa"), + border: InputBorder.none, + hintStyle: const TextStyle( + color: Color(0xffAEA4A3), + ), + fillColor: hexToColor("fafafa"), + filled: true, + isDense: true, + hintText: widget.hintText ?? '', + ), + controller: widget.textEditingController, + specialTextSpanBuilder: PlatformUtils().isWeb + ? null + : DefaultSpecialTextSpanBuilder( + isUseDefaultEmoji: + widget.isUseDefaultEmoji, + customEmojiStickerList: + widget.customEmojiStickerList, + showAtBackground: true, + )), + ), + ), + ], + ), + ), + ], + ), + )); + } +} diff --git a/lib/ui/views/TIMUIKitChat/tim_uikit_chat.dart b/lib/ui/views/TIMUIKitChat/tim_uikit_chat.dart index 27d3158..a294e8f 100644 --- a/lib/ui/views/TIMUIKitChat/tim_uikit_chat.dart +++ b/lib/ui/views/TIMUIKitChat/tim_uikit_chat.dart @@ -1,5 +1,6 @@ // ignore_for_file: must_be_immutable, avoid_print +import 'package:desktop_drop/desktop_drop.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -16,7 +17,9 @@ import 'package:tencent_cloud_chat_uikit/ui/constants/history_message_constant.d import 'package:tencent_cloud_chat_uikit/ui/controller/tim_uikit_chat_controller.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/frame.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_multi_select_panel.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/tim_uikit_send_file.dart'; import 'TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue.dart'; import 'TIMUIKItMessageList/tim_uikit_chat_history_message_list_config.dart'; import 'TIMUIKItMessageList/tim_uikit_history_message_list_container.dart'; @@ -27,7 +30,7 @@ class TIMUIKitChat extends StatefulWidget { int endTime = 0; /// The chat controller you tend to used. - /// You have to provide this before using it after tencent_cloud_chat_uikit 0.1.4. + /// You have to provide this before using it since tencent_cloud_chat_uikit 0.1.4. final TIMUIKitChatController? controller; /// [Update] It is suggested to provide the `V2TimConversation` once directly, since tencent_cloud_chat_uikit 1.5.0. @@ -41,6 +44,7 @@ class TIMUIKitChat extends StatefulWidget { /// This field is not necessary to be provided, when `conversation` is provided, unless you want to cover this field manually. final String? conversationID; + /// Conversation type. /// This field is not necessary to be provided, when `conversation` is provided, unless you want to cover this field manually. final ConvType? conversationType; @@ -48,11 +52,12 @@ class TIMUIKitChat extends StatefulWidget { final Widget Function(BuildContext context, V2TimMessage message)? userAvatarBuilder; + /// Use for show conversation name. /// This field is not necessary to be provided, when `conversation` is provided, unless you want to cover this field manually. final String? conversationShowName; /// Avatar and name in message reaction tap callback. - final void Function(String userID)? onTapAvatar; + final void Function(String userID, TapDownDetails tapDetails)? onTapAvatar; @Deprecated( "Nickname will not shows in one-to-one chat, if you tend to control it in group chat, please use `isShowSelfNameInGroup` and `isShowOthersNameInGroup` from `config: TIMUIKitChatConfig` instead") @@ -123,15 +128,10 @@ class TIMUIKitChat extends StatefulWidget { final List customEmojiStickerList; + final Widget? customAppBar; + /// Custom emoji panel. - final Widget Function( - {void Function() sendTextMessage, - void Function(int index, String data) sendFaceMessage, - void Function() deleteText, - void Function(int unicode) addText, - void Function(String singleEmojiName) addCustomEmojiText, - List defaultCustomEmojiStickerList})? - customStickerPanel; + final CustomStickerPanel? customStickerPanel; /// Custom text field final Widget Function(BuildContext context)? textFieldBuilder; @@ -139,6 +139,7 @@ class TIMUIKitChat extends StatefulWidget { TIMUIKitChat( {Key? key, this.groupID, + required this.conversation, this.conversationID, this.conversationType, this.conversationShowName, @@ -169,7 +170,7 @@ class TIMUIKitChat extends StatefulWidget { this.topFixWidget = const SizedBox(), this.textFieldBuilder, this.customEmojiStickerList = const [], - required this.conversation}) + this.customAppBar}) : super(key: key) { startTime = DateTime.now().millisecondsSinceEpoch; } @@ -179,11 +180,14 @@ class TIMUIKitChat extends StatefulWidget { } class _TUIChatState extends TIMUIKitState { - final TUIChatSeparateViewModel model = TUIChatSeparateViewModel(); + TUIChatSeparateViewModel model = TUIChatSeparateViewModel(); final TUIThemeViewModel themeViewModel = serviceLocator(); final TIMUIKitInputTextFieldController textFieldController = TIMUIKitInputTextFieldController(); bool isInit = false; + final TUIChatGlobalModel chatGlobalModel = + serviceLocator(); + bool _dragging = false; final GlobalKey alignKey = GlobalKey(); final GlobalKey listContainerKey = GlobalKey(); @@ -194,23 +198,11 @@ class _TUIChatState extends TIMUIKitState { axis: Axis.vertical, ); - String _getTitle() { - return TencentUtils.checkString(widget.conversationShowName) ?? - widget.conversation.showName ?? - "Chat"; - } - - String _getConvID() { - return TencentUtils.checkString(widget.conversationID) ?? - (widget.conversation.type == 1 - ? widget.conversation.userID - : widget.conversation.groupID) ?? - ""; - } - - ConvType _getConvType() { - return widget.conversation.type == 1 ? ConvType.c2c : ConvType.group; - } + late AutoScrollController atMemberPanelScroll = AutoScrollController( + viewportBoundaryGetter: () => + Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom), + axis: Axis.vertical, + ); @override void initState() { @@ -220,7 +212,7 @@ class _TUIChatState extends TIMUIKitState { } model.abstractMessageBuilder = widget.abstractMessageBuilder; model.onTapAvatar = widget.onTapAvatar; - WidgetsBinding.instance?.addPostFrameCallback((_) async { + WidgetsBinding.instance.addPostFrameCallback((_) async { if (kProfileMode) { widget.endTime = DateTime.now().millisecondsSinceEpoch; int timeSpend = widget.endTime - widget.startTime; @@ -238,6 +230,29 @@ class _TUIChatState extends TIMUIKitState { model.dispose(); } + @override + void didUpdateWidget(TIMUIKitChat oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.conversationID != oldWidget.conversationID) { + isInit = false; + chatGlobalModel.clearCurrentConversation(); + model = TUIChatSeparateViewModel(); + model.abstractMessageBuilder = widget.abstractMessageBuilder; + model.onTapAvatar = widget.onTapAvatar; + Future.delayed(const Duration(milliseconds: 50), () { + try { + autoController.jumpTo( + autoController.position.minScrollExtent, + ); + autoController.jumpTo( + autoController.position.minScrollExtent, + ); + // ignore: empty_catches + } catch (e) {} + }); + } + } + Widget _renderJoinGroupApplication(int amount, TUITheme theme) { String option1 = amount.toString(); return Container( @@ -273,6 +288,24 @@ class _TUIChatState extends TIMUIKitState { ); } + String _getTitle() { + return TencentUtils.checkString(widget.conversationShowName) ?? + widget.conversation.showName ?? + "Chat"; + } + + String _getConvID() { + return TencentUtils.checkString(widget.conversationID) ?? + (widget.conversation.type == 1 + ? widget.conversation.userID + : widget.conversation.groupID) ?? + ""; + } + + ConvType _getConvType() { + return widget.conversation.type == 1 ? ConvType.c2c : ConvType.group; + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; @@ -299,11 +332,11 @@ class _TUIChatState extends TIMUIKitState { widget.controller?.model = model; List filteredApplicationList = []; - if (_getConvType() == ConvType.group && + if (widget.conversationType == ConvType.group && widget.onDealWithGroupApplication != null) { filteredApplicationList = chatGlobalModel.groupApplicationList.where((item) { - return (item.groupID == _getConvID()) && + return (item.groupID == widget.conversationID) && item.handleStatus == 0; }).toList(); } @@ -312,7 +345,7 @@ class _TUIChatState extends TIMUIKitState { Provider.of(context, listen: true); final NeedUpdate? needUpdate = groupListenerModel.needUpdate; if (needUpdate != null && - needUpdate.groupID == _getConvID()) { + needUpdate.groupID == widget.conversationID) { groupListenerModel.needUpdate = null; switch (needUpdate.updateType) { case UpdateType.groupInfo: @@ -327,116 +360,160 @@ class _TUIChatState extends TIMUIKitState { } } - final alignBox = - alignKey.currentContext?.findRenderObject() as RenderBox?; - final alignHeight = alignBox?.size.height ?? 0; - - final listContainerBox = - listContainerKey.currentContext?.findRenderObject() as RenderBox?; - final listContainerBoxHeight = listContainerBox?.size.height ?? 0; - return GestureDetector( onTap: () { textFieldController.hideAllPanel(); }, child: Scaffold( resizeToAvoidBottomInset: false, - appBar: TIMUIKitAppBar( - showTotalUnReadCount: widget.showTotalUnReadCount, - config: widget.appBarConfig, - conversationShowName: _getTitle(), - conversationID: _getConvID(), - showC2cMessageEditStaus: - widget.config?.showC2cMessageEditStaus ?? true, - ), - body: Column( - children: [ - if (filteredApplicationList.isNotEmpty) - _renderJoinGroupApplication( - filteredApplicationList.length, theme), - if (widget.topFixWidget != null) widget.topFixWidget!, - Expanded( - child: Align( - key: alignKey, - alignment: Alignment.topCenter, - child: Listener( - onPointerMove: closePanel, - child: TIMUIKitHistoryMessageListContainer( - conversation: widget.conversation, - textFieldController: textFieldController, - customEmojiStickerList: - widget.customEmojiStickerList, - isUseDefaultEmoji: - widget.config!.isUseDefaultEmoji, - key: listContainerKey, - isAllowScroll: - (!(listContainerBoxHeight < alignHeight)), - userAvatarBuilder: widget.userAvatarBuilder, - toolTipsConfig: widget.toolTipsConfig, - groupAtInfoList: widget.groupAtInfoList, - tongueItemBuilder: widget.tongueItemBuilder, - onLongPressForOthersHeadPortrait: - (String? userId, String? nickName) { - if (_getConvType() != ConvType.c2c) { - textFieldController.longPressToAt( - nickName, userId); - } - }, - mainHistoryListConfig: - widget.mainHistoryListConfig, - initFindingMsg: widget.initFindingMsg, - extraTipsActionItemBuilder: - widget.extraTipsActionItemBuilder ?? - widget.exteraTipsActionItemBuilder, - conversationType: _getConvType(), - scrollController: autoController, - onTapAvatar: widget.onTapAvatar, - // ignore: deprecated_member_use_from_same_package - showNickName: widget.showNickName, - messageItemBuilder: widget.messageItemBuilder, - conversationID: _getConvID(), - ), - ))), - Selector( - builder: (context, value, child) { - return value - ? MultiSelectPanel( - conversationType: _getConvType(), - ) - : (widget.textFieldBuilder != null - ? widget.textFieldBuilder!(context) - : TIMUIKitInputTextField( - groupType: widget.conversation.groupType, - model: model, - controller: textFieldController, + appBar: (widget.customAppBar == null) + ? TIMUIKitAppBar( + showTotalUnReadCount: widget.showTotalUnReadCount, + config: widget.appBarConfig, + conversationShowName: _getTitle(), + conversationID: _getConvID(), + showC2cMessageEditStatus: + widget.config?.showC2cMessageEditStatus ?? true, + ) + : null, + body: DropTarget( + onDragDone: (detail) { + setState(() { + _dragging = false; + sendFileWithConfirmation( + files: detail.files, + conversation: widget.conversation, + conversationType: _getConvType(), + model: model, + theme: theme, + context: context); + }); + }, + onDragEntered: (detail) { + setState(() { + _dragging = true; + }); + }, + onDragExited: (detail) { + setState(() { + _dragging = false; + }); + }, + child: Stack( + children: [ + Column( + children: [ + if (widget.customAppBar != null) widget.customAppBar!, + if (filteredApplicationList.isNotEmpty) + _renderJoinGroupApplication( + filteredApplicationList.length, theme), + if (widget.topFixWidget != null) widget.topFixWidget!, + Expanded( + child: Container( + color: theme.chatBgColor, + child: Align( + key: alignKey, + alignment: Alignment.topCenter, + child: Listener( + onPointerMove: closePanel, + child: TIMUIKitHistoryMessageListContainer( + conversation: widget.conversation, + textFieldController: textFieldController, customEmojiStickerList: widget.customEmojiStickerList, isUseDefaultEmoji: widget.config!.isUseDefaultEmoji, - customStickerPanel: - widget.customStickerPanel, - morePanelConfig: widget.morePanelConfig, - scrollController: autoController, - conversationID: _getConvID(), + key: listContainerKey, + isAllowScroll: true, + userAvatarBuilder: widget.userAvatarBuilder, + toolTipsConfig: widget.toolTipsConfig, + groupAtInfoList: widget.groupAtInfoList, + tongueItemBuilder: widget.tongueItemBuilder, + onLongPressForOthersHeadPortrait: + (String? userId, String? nickName) { + if (widget.conversationType != + ConvType.c2c) { + textFieldController.longPressToAt( + nickName, userId); + } + }, + mainHistoryListConfig: + widget.mainHistoryListConfig, + initFindingMsg: widget.initFindingMsg, + extraTipsActionItemBuilder: + widget.extraTipsActionItemBuilder ?? + widget.exteraTipsActionItemBuilder, conversationType: _getConvType(), - initText: widget.draftText, - hintText: widget.textFieldHintText, - showMorePanel: - widget.config?.isAllowShowMorePanel ?? - true, - showSendAudio: - widget.config?.isAllowSoundMessage ?? - true, - showSendEmoji: - widget.config?.isAllowEmojiPanel ?? - true, - )); - }, - selector: (c, model) { - return model.isMultiSelect; - }, - ) - ], + scrollController: autoController, + onTapAvatar: widget.onTapAvatar, + // ignore: deprecated_member_use_from_same_package + showNickName: widget.showNickName, + messageItemBuilder: + widget.messageItemBuilder, + conversationID: _getConvID(), + ), + )), + )), + Selector( + builder: (context, value, child) { + return value + ? MultiSelectPanel( + conversationType: _getConvType(), + ) + : (widget.textFieldBuilder != null + ? widget.textFieldBuilder!(context) + : TIMUIKitInputTextField( + key: inputTextFieldState, + atMemberPanelScroll: + atMemberPanelScroll, + groupType: + widget.conversation.groupType, + currentConversation: + widget.conversation, + model: model, + controller: textFieldController, + customEmojiStickerList: + widget.customEmojiStickerList, + isUseDefaultEmoji: + widget.config!.isUseDefaultEmoji, + customStickerPanel: + widget.customStickerPanel, + morePanelConfig: + widget.morePanelConfig, + scrollController: autoController, + conversationID: _getConvID(), + conversationType: _getConvType(), + initText: widget.draftText, + hintText: widget.textFieldHintText, + showMorePanel: widget.config + ?.isAllowShowMorePanel ?? + true, + showSendAudio: widget.config + ?.isAllowSoundMessage ?? + true, + showSendEmoji: widget + .config?.isAllowEmojiPanel ?? + true, + )); + }, + selector: (c, model) { + return model.isMultiSelect; + }, + ) + ], + ), + if (_dragging) + TIMUIKitSendFile( + conversation: widget.conversation, + ), + AtMemberPanel( + atMemberPanelScroll: atMemberPanelScroll, + onSelectMember: (member) => inputTextFieldState + .currentState + ?.handleAtMember(memberInfo: member), + ) + ], + ), )), ); }); @@ -511,14 +588,15 @@ class TIMUIKitChatProviderScope extends StatelessWidget { groupID: groupID, ); model?.showC2cMessageEditStatus = (conversationType == ConvType.c2c - ? config?.showC2cMessageEditStaus ?? true + ? config?.showC2cMessageEditStatus ?? true : false); loadData(); } loadData() { // if (model!.haveMoreData) { - model!.loadData(count: kIsWeb ? 15 : HistoryMessageDartConstant.getCount); + model!.loadChatRecord( + count: kIsWeb ? 15 : HistoryMessageDartConstant.getCount); // } } diff --git a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart index be2bef1..7096a47 100644 --- a/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart +++ b/lib/ui/views/TIMUIKitChat/tim_uikit_chat_config.dart @@ -1,6 +1,8 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'TIMUIKitTextField/tim_uikit_text_field_layout/wide.dart'; + enum GroupReceptAllowType { work, public, meeting } enum GroupReceiptAllowType { work, public, meeting } @@ -36,7 +38,7 @@ class TIMUIKitChatConfig { /// [Default]: true. final bool isReportGroupReadingStatus; - /// Control if allowed to show the menu after long pressing message. + /// Control if allowed to show the message operation menu after long pressing message. /// [Default]: true. final bool isAllowLongPressMessage; @@ -77,6 +79,11 @@ class TIMUIKitChatConfig { /// [Default]: true. final bool isShowOthersNameInGroup; + /// Configuration for offline push. + /// If this field is specified, `notificationTitle`, `notificationOPPOChannelID`, `notificationIOSSound`, `notificationAndroidSound`, `notificationBody` and `notificationExt` will not work. + final OfflinePushInfo? Function( + V2TimMessage message, String convID, ConvType convType)? offlinePushInfo; + /// The title shows in push notification final String notificationTitle; @@ -91,7 +98,7 @@ class TIMUIKitChatConfig { final String notificationAndroidSound; ///Used to set the line height of text messages - final double textHight; + final double textHeight; /// The body content shows in push notification. /// Returning `null` means using default body in this case. @@ -109,7 +116,7 @@ class TIMUIKitChatConfig { /// Whether to display the sending status of c2c messages /// [Default]: true. - final bool showC2cMessageEditStaus; + final bool showC2cMessageEditStatus; /// Control if take emoji stickers as message reaction. /// [Default]: true. @@ -127,7 +134,9 @@ class TIMUIKitChatConfig { /// The suffix of face sticker URI. final String Function(String data)? faceURISuffix; - /// Control if text and replied messages can be show with markdown. + /// Controls whether text and replied messages can be displayed with Markdown formatting. + /// When enabled, small image stickers, including QQ stickers, will not work in message items. + /// Also, when enabled, `isEnableTextSelection` will not works. /// [Default]: false. final bool isSupportMarkdownForTextMessage; @@ -142,12 +151,40 @@ class TIMUIKitChatConfig { /// [Default]: true. final bool isShowAvatar; + /// This list contains additional operation items that are displayed on the hover bar + /// of a message on desktop (macOS, Windows, and desktop version of Web). These items + /// are in addition to the default ones and do not affect them. + final List? additionalDesktopMessageHoverBarItem; + + /// This list contains additional items that are displayed + /// on the control bar on desktop (macOS, Windows, and desktop version of Web). + /// Use `desktopControlBarConfig` to configure whether or not to show the default control items. + final List? additionalDesktopControlBarItems; + + /// This configuration is used for the control bar + /// on desktop (macOS, Windows, and desktop version of Web). + /// Use `desktopControlBarConfig` to add additional items to the desktop control bar, in addition to the default ones. + final DesktopControlBarConfig? desktopControlBarConfig; + + /// Controls whether users are allowed to mention another user in the group by long-pressing on their avatar. + /// [Default]: true. + final bool isAllowLongPressAvatarToAt; + + /// Controls whether auto report message read status when new messages come. + /// [Default]: true. + final bool isAutoReportRead; + + /// Controls whether enable text selection. + /// [Default]: true on Desktop while false on Mobile. + final bool? isEnableTextSelection; + const TIMUIKitChatConfig( {this.onTapLink, this.timeDividerConfig, + this.isAutoReportRead = true, this.faceURIPrefix, this.faceURISuffix, - this.textHight = 1.0, + this.textHeight = 1.3, this.isAtWhenReply = true, this.notificationAndroidSound = "", this.isSupportMarkdownForTextMessage = false, @@ -155,6 +192,7 @@ class TIMUIKitChatConfig { this.isUseMessageReaction = true, this.isShowAvatar = true, this.isShowSelfNameInGroup = false, + this.offlinePushInfo, @Deprecated("Please use [isShowGroupReadingStatus] instead") this.isShowGroupMessageReadReceipt = true, this.upperRecallTime = 120, @@ -171,10 +209,15 @@ class TIMUIKitChatConfig { this.isAllowEmojiPanel = true, this.isAllowShowMorePanel = true, this.isShowReadingStatus = true, + this.desktopControlBarConfig, this.isAllowLongPressMessage = true, this.isAllowClickAvatar = true, + this.isEnableTextSelection, + this.additionalDesktopMessageHoverBarItem, this.isShowGroupReadingStatus = true, this.isReportGroupReadingStatus = true, - this.showC2cMessageEditStaus = true, + this.showC2cMessageEditStatus = true, + this.additionalDesktopControlBarItems, + this.isAllowLongPressAvatarToAt = true, this.isUseDefaultEmoji = false}); } diff --git a/lib/ui/views/TIMUIKitChat/tim_uikit_multi_select_panel.dart b/lib/ui/views/TIMUIKitChat/tim_uikit_multi_select_panel.dart index 02dfa76..93f2be6 100644 --- a/lib/ui/views/TIMUIKitChat/tim_uikit_multi_select_panel.dart +++ b/lib/ui/views/TIMUIKitChat/tim_uikit_multi_select_panel.dart @@ -4,8 +4,11 @@ import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/forward_message_screen.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; @@ -28,102 +31,221 @@ class MultiSelectPanel extends TIMUIKitStatelessWidget { ))); } + _handleForwardMessageWide(BuildContext context, bool isMergerForward, + TUIChatSeparateViewModel model) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.forward, + context: context, + isDarkBackground: false, + title: TIM_t("转发"), + submitWidget: Text(TIM_t("发送")), + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.8, + onSubmit: (){ + forwardMessageScreenKey.currentState?.handleForwardMessage(); + }, + child: (onClose) => Container( + padding: const EdgeInsets.symmetric( horizontal: 10), + child: ForwardMessageScreen( + model: model, + key: forwardMessageScreenKey, + onClose: onClose, + isMergerForward: isMergerForward, + conversationType: conversationType, + ), + ) + ); + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; final TUIChatSeparateViewModel model = Provider.of(context); - return Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - padding: const EdgeInsets.only(top: 12, bottom: 48), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Column( - children: [ - IconButton( - icon: Image.asset('images/forward.png', - package: 'tencent_cloud_chat_uikit', color: theme.white), - iconSize: 40, - onPressed: () { - _handleForwardMessage(context, false, model); - }, - ), - Text(TIM_t("逐条转发"), - style: TextStyle(color: theme.white, fontSize: 12)) - ], + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: Container( + decoration: BoxDecoration( + color: theme.selectPanelBgColor ?? theme.primaryColor, + border: Border( + top: BorderSide( + color: theme.weakDividerColor ?? Colors.grey, + width: 1.0, + ), ), - Column( - children: [ - IconButton( - icon: Image.asset('images/merge_forward.png', - package: 'tencent_cloud_chat_uikit', color: theme.white), - iconSize: 40, - onPressed: () { - _handleForwardMessage(context, true, model); - }, - ), - Text( - TIM_t("合并转发"), - style: TextStyle(color: theme.white, fontSize: 12), - ) - ], - ), - Column( - children: [ - IconButton( - icon: Image.asset('images/delete.png', - package: 'tencent_cloud_chat_uikit', color: theme.white), - iconSize: 40, - onPressed: () { - showCupertinoModalPopup( - context: context, - builder: (BuildContext context) { - return CupertinoActionSheet( - title: Text(TIM_t("确定删除已选消息")), - cancelButton: CupertinoActionSheetAction( - onPressed: () { - Navigator.pop( - context, - "cancel", - ); - }, - child: Text(TIM_t("取消")), - isDefaultAction: false, - ), - actions: [ - CupertinoActionSheetAction( - onPressed: () { + ), + padding: const EdgeInsets.symmetric(vertical: 32), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Expanded( + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + alignment: WrapAlignment.center, + spacing: 64, + children: [ + Column( + children: [ + IconButton( + icon: Image.asset('images/forward.png', + package: 'tencent_cloud_chat_uikit', + color: theme.selectPanelTextIconColor), + iconSize: 30, + onPressed: () { + _handleForwardMessageWide(context, false, model); + }, + ), + Text(TIM_t("逐条转发"), + style: TextStyle( + color: hexToColor("646a73"), fontSize: 12)) + ], + ), + Column( + children: [ + IconButton( + icon: Image.asset('images/merge_forward.png', + package: 'tencent_cloud_chat_uikit', + color: theme.selectPanelTextIconColor), + iconSize: 30, + onPressed: () { + _handleForwardMessageWide(context, true, model); + }, + ), + Text( + TIM_t("合并转发"), + style: + TextStyle(color: theme.selectPanelTextIconColor, fontSize: 12), + ) + ], + ), + Column( + children: [ + IconButton( + icon: Image.asset('images/delete.png', + package: 'tencent_cloud_chat_uikit', + color: theme.selectPanelTextIconColor), + iconSize: 30, + onPressed: () { + TUIKitWidePopup.showSecondaryConfirmDialog( + operationKey: TUIKitWideModalOperationKey.confirmDeleteMessages, + context: context, + text: TIM_t("确定删除已选消息"), + theme: theme, + onCancel: () {}, + onConfirm: () async { model.deleteSelectedMsg(); model.updateMultiSelectStatus(false); + }); + }, + ), + Text(TIM_t("删除"), + style: TextStyle( + color: theme.selectPanelTextIconColor, fontSize: 12)) + ], + ), + InkWell( + onTap: (){ + model.updateMultiSelectStatus(false); + }, + child: Icon(Icons.close, color: theme.darkTextColor,), + ) + ], + )) + ], + ), + ), + defaultWidget: Container( + decoration: BoxDecoration( + border: Border( + top: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor)), + color: theme.selectPanelBgColor ?? theme.primaryColor, + ), + padding: const EdgeInsets.only(top: 12, bottom: 48), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + IconButton( + icon: Image.asset('images/forward.png', + package: 'tencent_cloud_chat_uikit', color: theme.selectPanelTextIconColor), + iconSize: 40, + onPressed: () { + _handleForwardMessage(context, false, model); + }, + ), + Text(TIM_t("逐条转发"), + style: TextStyle(color: theme.selectPanelTextIconColor, fontSize: 12)) + ], + ), + Column( + children: [ + IconButton( + icon: Image.asset('images/merge_forward.png', + package: 'tencent_cloud_chat_uikit', color: theme.selectPanelTextIconColor), + iconSize: 40, + onPressed: () { + _handleForwardMessage(context, true, model); + }, + ), + Text( + TIM_t("合并转发"), + style: TextStyle(color: theme.selectPanelTextIconColor, fontSize: 12), + ) + ], + ), + Column( + children: [ + IconButton( + icon: Image.asset('images/delete.png', + package: 'tencent_cloud_chat_uikit', color: theme.selectPanelTextIconColor), + iconSize: 40, + onPressed: () { + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) { + return CupertinoActionSheet( + title: Text(TIM_t("确定删除已选消息")), + cancelButton: CupertinoActionSheetAction( + onPressed: () { Navigator.pop( context, "cancel", ); }, - child: Text( - TIM_t("删除"), - style: TextStyle(color: theme.cautionColor), - ), + child: Text(TIM_t("取消")), isDefaultAction: false, - ) - ], - ); - }, - ); - }, - ), - Text(TIM_t("删除"), - style: TextStyle(color: theme.white, fontSize: 12)) - ], - ) - ], + ), + actions: [ + CupertinoActionSheetAction( + onPressed: () { + model.deleteSelectedMsg(); + model.updateMultiSelectStatus(false); + Navigator.pop( + context, + "cancel", + ); + }, + child: Text( + TIM_t("删除"), + style: TextStyle(color: theme.cautionColor), + ), + isDefaultAction: false, + ) + ], + ); + }, + ); + }, + ), + Text(TIM_t("删除"), + style: TextStyle(color: theme.selectPanelTextIconColor, fontSize: 12)) + ], + ) + ], + ), ), ); } diff --git a/lib/ui/views/TIMUIKitChat/tim_uikit_send_file.dart b/lib/ui/views/TIMUIKitChat/tim_uikit_send_file.dart new file mode 100644 index 0000000..60bcbb0 --- /dev/null +++ b/lib/ui/views/TIMUIKitChat/tim_uikit_send_file.dart @@ -0,0 +1,227 @@ +import 'dart:io'; +import 'package:dotted_border/dotted_border.dart'; +import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:cross_file/cross_file.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; +import 'package:path/path.dart' as path; +import 'package:url_launcher/url_launcher.dart'; + +import 'TIMUIKitMessageItem/tim_uikit_chat_file_icon.dart'; + +String _getConvID(V2TimConversation conversation) { + return (conversation.type == 1 + ? conversation.userID + : conversation.groupID) ?? + ""; +} + +sendFileWithConfirmation( + {required List files, + required V2TimConversation conversation, + required ConvType conversationType, + required TUIChatSeparateViewModel model, + required TUITheme theme, + required BuildContext context}) async { + bool isCanSend = true; + + files.map((e) => e.path).any((filePath) { + final directory = Directory(filePath); + final isDirectoryExists = directory.existsSync(); + if (isDirectoryExists) { + isCanSend = false; + return false; + } + return true; + }); + + if (!isCanSend) { + TUIKitWidePopup.showSecondaryConfirmDialog( + text: TIM_t("无法发送,包含文件夹"), + onConfirm: () {}, + operationKey: TUIKitWideModalOperationKey.unableToSendDueToFolders, + context: context, + theme: theme); + return; + } + + final option1 = conversation.showName ?? + (conversationType == ConvType.group ? TIM_t("群聊") : TIM_t("对方")); + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.beforeSendScreenShot, + context: context, + isDarkBackground: false, + width: 600, + height: files.length < 4 ? 300 : 500, + title: TIM_t_para("发送给{{option1}}", "发送给$option1")(option1: option1), + child: (closeFunc) => Container( + padding: const EdgeInsets.only(bottom: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Scrollbar( + child: ListView.separated( + itemBuilder: (BuildContext context, int index) { + final file = files[index]; + return Material( + color: theme.wideBackgroundColor, + child: InkWell( + onTap: () { + launchUrl(Uri.file(file.path)); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 6, horizontal: 20), + child: Row( + children: [ + TIMUIKitFileIcon( + size: 44, + fileFormat: path + .extension(file.path) + .split(".")[path + .extension(file.path) + .split(".") + .length - + 1], + ), + const SizedBox(width: 16), + Expanded( + child: Text( + path.basename(file.path), + style: TextStyle( + fontSize: 16, + color: theme.darkTextColor), + ), + ), + ], + ), + ), + ), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return Divider( + height: 1, + thickness: 1, + color: theme.weakDividerColor, + ); + }, + itemCount: files.length, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 16, top: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + OutlinedButton( + onPressed: () { + closeFunc(); + }, + child: Text(TIM_t("取消"))), + const SizedBox( + width: 20, + ), + ElevatedButton( + onPressed: () { + sendFiles(files, model, conversation, + conversationType, context); + closeFunc(); + }, + child: Text(TIM_t("发送"))) + ], + ), + ) + ], + ), + )); +} + +Future sendFiles( + List files, + TUIChatSeparateViewModel model, + V2TimConversation conversation, + ConvType conversationType, + BuildContext context) async { + for (final file in files) { + await MessageUtils.handleMessageError( + model.sendFileMessage( + filePath: file.path, + convID: _getConvID(conversation), + convType: conversationType), + context); + await Future.delayed(const Duration(microseconds: 300)); + } +} + +class TIMUIKitSendFile extends TIMUIKitStatelessWidget { + final V2TimConversation conversation; + + TIMUIKitSendFile({required this.conversation, Key? key}) : super(key: key); + + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; + final conversationType = conversation.type; + final option1 = conversation.showName ?? + (conversationType == 2 ? TIM_t("群聊") : TIM_t("会话")); + + return Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Opacity( + opacity: 0.85, + child: Container( + color: theme.wideBackgroundColor, + padding: const EdgeInsets.all(40), + child: DottedBorder( + borderType: BorderType.RRect, + radius: const Radius.circular(20), + color: theme.primaryColor ?? theme.weakTextColor!, + dashPattern: const [6, 3], + child: Row( + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.file_copy_outlined, + size: 60, + color: theme.primaryColor, + ), + const SizedBox( + height: 40, + ), + Text( + TIM_t_para("发送给{{option1}}", "发送给$option1")( + option1: option1), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: theme.darkTextColor), + ) + ], + )) + ], + ), + ), + ), + )) + ], + ); + } +} diff --git a/lib/ui/views/TIMUIKitContact/tim_uikit_contact.dart b/lib/ui/views/TIMUIKitContact/tim_uikit_contact.dart index 2e1651e..9e8318b 100644 --- a/lib/ui/views/TIMUIKitContact/tim_uikit_contact.dart +++ b/lib/ui/views/TIMUIKitContact/tim_uikit_contact.dart @@ -8,6 +8,7 @@ import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; export 'package:tencent_cloud_chat_uikit/ui/widgets/contact_list.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; class TIMUIKitContact extends StatefulWidget { /// the callback after clicking contact item @@ -44,11 +45,8 @@ class TIMUIKitContact extends StatefulWidget { class _TIMUIKitContactState extends TIMUIKitState { final TUIFriendShipViewModel model = serviceLocator(); + String currentItem = ""; - @override - void initState() { - super.initState(); - } @override void dispose() { @@ -57,6 +55,8 @@ class _TIMUIKitContactState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return MultiProvider( providers: [ ChangeNotifierProvider.value(value: model), @@ -67,10 +67,21 @@ class _TIMUIKitContactState extends TIMUIKitState { final memberList = model.friendList ?? []; return ContactList( + currentItem: currentItem, emptyBuilder: widget.emptyBuilder, isShowOnlineStatus: widget.isShowOnlineStatus, contactList: memberList, - onTapItem: widget.onTapItem, + onTapItem: (item){ + if(isDesktopScreen){ + setState(() { + currentItem = item.userID; + }); + } + if(widget.onTapItem != null){ + widget.onTapItem!(item); + } + }, + bgColor: isDesktopScreen ? theme.wideBackgroundColor : null, topList: widget.topList, topListItemBuilder: widget.topListItemBuilder, ); diff --git a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart index 08fbb03..5ec34e0 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_slidable_for_tencent_im/flutter_slidable.dart'; @@ -8,24 +10,27 @@ import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/conversation_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart'; - +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/controller/tim_uikit_conversation_controller.dart'; - import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/customize_ball_pulse_header.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; -import 'package:tencent_im_base/tencent_im_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; typedef ConversationItemBuilder = Widget Function( V2TimConversation conversationItem, [V2TimUserStatus? onlineStatus]); -typedef ConversationItemSlidableBuilder = List +typedef ConversationItemSlideBuilder = List Function(V2TimConversation conversationItem); +typedef ConversationItemSecondaryMenuBuilder = Widget Function( + V2TimConversation conversationItem, VoidCallback onClose); + class TIMUIKitConversation extends StatefulWidget { /// the callback after clicking conversation item final ValueChanged? onTapItem; @@ -34,10 +39,13 @@ class TIMUIKitConversation extends StatefulWidget { final TIMUIKitConversationController? controller; /// the builder for conversation item - final ConversationItemBuilder? itembuilder; + final ConversationItemBuilder? itemBuilder; - /// the builder for slidable item for each conversation item - final ConversationItemSlidableBuilder? itemSlidableBuilder; + /// the builder for Slidable item for each conversation item, shows on narrow screens. + final ConversationItemSlideBuilder? itemSlideBuilder; + + /// the widget of secondary tap menu for each conversation item, shows on wide screens. + final ConversationItemSecondaryMenuBuilder? itemSecondaryMenuBuilder; /// the widget shows when no conversation exists final Widget Function()? emptyBuilder; @@ -65,9 +73,10 @@ class TIMUIKitConversation extends StatefulWidget { this.lifeCycle, this.onTapItem, this.controller, - this.itembuilder, + this.itemSecondaryMenuBuilder, + this.itemBuilder, this.isShowDraft = true, - this.itemSlidableBuilder, + this.itemSlideBuilder, this.conversationCollector, this.emptyBuilder, this.lastMessageBuilder, @@ -80,8 +89,8 @@ class TIMUIKitConversation extends StatefulWidget { } } -class ConversationItemSlidablePanel extends TIMUIKitStatelessWidget { - ConversationItemSlidablePanel({ +class ConversationItemSlidePanel extends TIMUIKitStatelessWidget { + ConversationItemSlidePanel({ Key? key, this.flex = 1, this.backgroundColor = Colors.white, @@ -150,7 +159,7 @@ class _TIMUIKitConversationState extends TIMUIKitState { final controller = getController(); _timuiKitConversationController = controller; _timuiKitConversationController.model = model; - _autoScrollController = AutoScrollController(); + _autoScrollController = AutoScrollController(); } TIMUIKitConversationController getController() { @@ -180,46 +189,17 @@ class _TIMUIKitConversationState extends TIMUIKitState { conversationID: conversation.conversationID); } - List _defaultSlidableBuilder( - V2TimConversation conversationItem, - ) { - final theme = themeViewModel.theme; - return [ - if (!PlatformUtils().isWeb) - ConversationItemSlidablePanel( - onPressed: (context) { - _clearHistory(conversationItem); - }, - backgroundColor: theme.conversationItemSliderClearBgColor ?? - CommonColor.primaryColor, - foregroundColor: theme.conversationItemSliderTextColor, - label: TIM_t("清除聊天"), - spacing: 0, - autoClose: true, - ), - ConversationItemSlidablePanel( - onPressed: (context) { - _pinConversation(conversationItem); - }, - backgroundColor: - theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor, - foregroundColor: theme.conversationItemSliderTextColor, - label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"), - ), - ConversationItemSlidablePanel( - onPressed: (context) { - _deleteConversation(conversationItem); - }, - backgroundColor: - theme.conversationItemSliderDeleteBgColor ?? Colors.red, - foregroundColor: theme.conversationItemSliderTextColor, - label: TIM_t("删除"), - ) - ]; - } - - ConversationItemSlidableBuilder _getSlidableBuilder() { - return widget.itemSlidableBuilder ?? _defaultSlidableBuilder; + List getFilteredConversation() { + List filteredConversationList = model.conversationList + .where( + (element) => (element?.groupID != null || element?.userID != null)) + .toList(); + if (widget.conversationCollector != null) { + filteredConversationList = filteredConversationList + .where(widget.conversationCollector!) + .toList(); + } + return filteredConversationList; } _onScrollToConversation(String conversationID) { @@ -234,6 +214,7 @@ class _TIMUIKitConversationState extends TIMUIKitState { break; } } + if (isFound) { _autoScrollController.scrollToIndex( targetIndex, @@ -242,29 +223,98 @@ class _TIMUIKitConversationState extends TIMUIKitState { } } + Widget _defaultSecondaryMenu( + V2TimConversation conversationItem, VoidCallback onClose) { + return TUIKitColumnMenu(data: [ + if (!PlatformUtils().isWeb) + ColumnMenuItem( + label: TIM_t("清除消息"), + icon: const Icon(Icons.clear_all, size: 16), + onClick: () { + onClose(); + _clearHistory(conversationItem); + }), + ColumnMenuItem( + label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"), + icon: Icon( + conversationItem.isPinned! + ? Icons.vertical_align_bottom + : Icons.vertical_align_top, + size: 16), + onClick: () { + onClose(); + _pinConversation(conversationItem); + }), + ColumnMenuItem( + label: TIM_t("删除会话"), + icon: const Icon(Icons.delete_outline, size: 16), + onClick: () { + onClose(); + _deleteConversation(conversationItem); + }), + ]); + } + + List _defaultSlideBuilder( + V2TimConversation conversationItem, + ) { + final theme = themeViewModel.theme; + return [ + if (!PlatformUtils().isWeb) + ConversationItemSlidePanel( + onPressed: (context) { + _clearHistory(conversationItem); + }, + backgroundColor: theme.conversationItemSliderClearBgColor ?? + CommonColor.primaryColor, + foregroundColor: theme.conversationItemSliderTextColor, + label: TIM_t("清除聊天"), + spacing: 0, + autoClose: true, + ), + ConversationItemSlidePanel( + onPressed: (context) { + _pinConversation(conversationItem); + }, + backgroundColor: + theme.conversationItemSliderPinBgColor ?? CommonColor.infoColor, + foregroundColor: theme.conversationItemSliderTextColor, + label: conversationItem.isPinned! ? TIM_t("取消置顶") : TIM_t("置顶"), + ), + ConversationItemSlidePanel( + onPressed: (context) { + _deleteConversation(conversationItem); + }, + backgroundColor: + theme.conversationItemSliderDeleteBgColor ?? Colors.red, + foregroundColor: theme.conversationItemSliderTextColor, + label: TIM_t("删除"), + ) + ]; + } + + Widget _getSecondaryMenu( + V2TimConversation conversation, VoidCallback onClose) { + if (widget.itemSecondaryMenuBuilder != null) { + return widget.itemSecondaryMenuBuilder!(conversation, onClose); + } + return _defaultSecondaryMenu(conversation, onClose); + } + + ConversationItemSlideBuilder _getSlideBuilder() { + return widget.itemSlideBuilder ?? _defaultSlideBuilder; + } + @override void dispose() { super.dispose(); - // model.dispose(); - } - - List getFilteredConversation(){ - List filteredConversationList = model - .conversationList - .where((element) => - (element?.groupID != null || element?.userID != null)) - .toList(); - if (widget.conversationCollector != null) { - filteredConversationList = filteredConversationList - .where(widget.conversationCollector!) - .toList(); - } - return filteredConversationList; } @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return MultiProvider( providers: [ ChangeNotifierProvider.value(value: model), @@ -277,89 +327,141 @@ class _TIMUIKitConversationState extends TIMUIKitState { Provider.of(context); _model.lifeCycle = widget.lifeCycle; - List filteredConversationList = getFilteredConversation(); + List filteredConversationList = + getFilteredConversation(); - if(TencentUtils.checkString(_model.scrollToConversation) != null){ + if (TencentUtils.checkString(_model.scrollToConversation) != null) { _onScrollToConversation(_model.scrollToConversation!); _model.clearScrollToConversation(); } - return SlidableAutoCloseBehavior( - child: EasyRefresh( - header: CustomizeBallPulseHeader(color: theme.primaryColor), - onRefresh: () async { - model.refresh(); - }, - child: filteredConversationList.isNotEmpty - ? ListView.builder( - controller: _autoScrollController, - shrinkWrap: true, - itemCount: filteredConversationList.length, - itemBuilder: (context, index) { - if (index == filteredConversationList.length - 1) { - if (haveMoreData) { - _timuiKitConversationController.loadData(); - } + Widget conversationList() { + return filteredConversationList.isNotEmpty + ? ListView.builder( + controller: _autoScrollController, + shrinkWrap: true, + itemCount: filteredConversationList.length, + itemBuilder: (context, index) { + if (index == filteredConversationList.length - 1) { + if (haveMoreData) { + _timuiKitConversationController.loadData(); } + } - final conversationItem = - filteredConversationList[index]; + final conversationItem = filteredConversationList[index]; - final V2TimUserStatus? onlineStatus = - _friendShipViewModel.userStatusList.firstWhere( - (item) => - item.userID == conversationItem?.userID, - orElse: () => V2TimUserStatus(statusType: 0)); + final V2TimUserStatus? onlineStatus = + _friendShipViewModel.userStatusList.firstWhere( + (item) => item.userID == conversationItem?.userID, + orElse: () => V2TimUserStatus(statusType: 0)); - if (widget.itembuilder != null) { - return widget.itembuilder!( - conversationItem!, onlineStatus); - } + if (widget.itemBuilder != null) { + return widget.itemBuilder!( + conversationItem!, onlineStatus); + } - final slidableChildren = - _getSlidableBuilder()(conversationItem!); - return AutoScrollTag( + final slideChildren = + _getSlideBuilder()(conversationItem!); + + final isCurrent = conversationItem.conversationID == + model.selectedConversation?.conversationID; + + final isPined = conversationItem.isPinned ?? false; + + Widget conversationLineItem() { + return Material( + color: (isCurrent && isDesktopScreen) + ? theme.conversationItemChooseBgColor + : isPined + ? theme.conversationItemPinedBgColor + : theme.conversationItemBgColor, + child: InkWell( + child: TIMUIKitConversationItem( + isCurrent: isCurrent, + isShowDraft: widget.isShowDraft, + lastMessageBuilder: widget.lastMessageBuilder, + faceUrl: conversationItem.faceUrl ?? "", + nickName: conversationItem.showName ?? "", + isDisturb: conversationItem.recvOpt != 0, + lastMsg: conversationItem.lastMessage, + isPined: isPined, + groupAtInfoList: + conversationItem.groupAtInfoList ?? [], + unreadCount: conversationItem.unreadCount ?? 0, + draftText: conversationItem.draftText, + onlineStatus: (widget.isShowOnlineStatus && + conversationItem.userID != null && + conversationItem.userID!.isNotEmpty) + ? onlineStatus + : null, + draftTimestamp: conversationItem.draftTimestamp, + convType: conversationItem.type), + onTap: () => onTapConvItem(conversationItem), + ), + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: AutoScrollTag( key: ValueKey(conversationItem.conversationID), controller: _autoScrollController, index: index, - child: Slidable( - groupTag: 'conversation-list', - child: InkWell( - child: TIMUIKitConversationItem( - isShowDraft: widget.isShowDraft, - lastMessageBuilder: widget.lastMessageBuilder, - faceUrl: conversationItem.faceUrl ?? "", - nickName: conversationItem.showName ?? "", - isDisturb: conversationItem.recvOpt != 0, - lastMsg: conversationItem.lastMessage, - isPined: conversationItem.isPinned ?? false, - groupAtInfoList: - conversationItem.groupAtInfoList ?? [], - unreadCount: - conversationItem.unreadCount ?? 0, - draftText: conversationItem.draftText, - onlineStatus: (widget.isShowOnlineStatus && - conversationItem.userID != null && - conversationItem.userID!.isNotEmpty) - ? onlineStatus - : null, - draftTimestamp: - conversationItem.draftTimestamp, - convType: conversationItem.type), - onTap: () => onTapConvItem(conversationItem), - ), - endActionPane: ActionPane( - extentRatio: - slidableChildren.length > 2 ? 0.77 : 0.5, - motion: const DrawerMotion(), - children: slidableChildren)), - ); - }) - : (widget.emptyBuilder != null - ? widget.emptyBuilder!() - : Container()), - ), - ); + child: GestureDetector( + onSecondaryTapDown: (details) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey + .conversationSecondaryMenu, + isDarkBackground: false, + borderRadius: const BorderRadius.all( + Radius.circular(4)), + context: context, + offset: Offset( + min( + details.globalPosition.dx, + MediaQuery.of(context).size.width - + 80), + min( + details.globalPosition.dy, + MediaQuery.of(context).size.height - + 130)), + child: (onClose) => _getSecondaryMenu( + conversationItem, onClose)); + }, + child: conversationLineItem(), + ), + ), + defaultWidget: AutoScrollTag( + key: ValueKey(conversationItem.conversationID), + controller: _autoScrollController, + index: index, + child: Slidable( + groupTag: 'conversation-list', + child: conversationLineItem(), + endActionPane: ActionPane( + extentRatio: + slideChildren.length > 2 ? 0.77 : 0.5, + motion: const DrawerMotion(), + children: slideChildren)), + )); + }) + : (widget.emptyBuilder != null + ? widget.emptyBuilder!() + : Container()); + } + + return TUIKitScreenUtils.getDeviceWidget( + defaultWidget: SlidableAutoCloseBehavior( + child: EasyRefresh( + header: CustomizeBallPulseHeader(color: theme.primaryColor), + onRefresh: () async { + model.refresh(); + }, + child: conversationList(), + ), + ), + desktopWidget: Scrollbar( + controller: _autoScrollController, + child: conversationList())); }); } } diff --git a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_draft_text.dart b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_draft_text.dart index e7b7d2f..ff1dc94 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_draft_text.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_draft_text.dart @@ -7,9 +7,11 @@ import 'package:tencent_im_base/tencent_im_base.dart'; class TIMUIKitDraftText extends TIMUIKitStatelessWidget { final BuildContext context; final String draftText; + final double fontSize; TIMUIKitDraftText({ Key? key, + this.fontSize = 14.0, required this.context, required this.draftText, }) : super(key: key); @@ -37,7 +39,7 @@ class TIMUIKitDraftText extends TIMUIKitStatelessWidget { style: TextStyle( height: 1.5, color: theme.conversationItemLastMessageTextColor, - fontSize: 14), + fontSize: fontSize), )), ]); } diff --git a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart index ae07634..0a1c692 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_item.dart @@ -1,6 +1,7 @@ -// ignore_for_file: avoid_print, empty_catches +// ignore_for_file: empty_catches import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; @@ -28,6 +29,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { final LastMessageBuilder? lastMessageBuilder; final V2TimUserStatus? onlineStatus; final int? convType; + final bool isCurrent; /// Control if shows the identifier that the conversation has a draft text, inputted in previous. /// Also, you'd better specifying the `draftText` field for `TIMUIKitChat`, from the `draftText` in `V2TimConversation`, @@ -42,6 +44,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { required this.lastMsg, this.onlineStatus, required this.isPined, + this.isCurrent = false, required this.unreadCount, required this.groupAtInfoList, required this.isDisturb, @@ -52,10 +55,12 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { }) : super(key: key); Widget _getShowMsgWidget(BuildContext context) { + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (isShowDraft && draftText != null && draftText != "") { return TIMUIKitDraftText( context: context, draftText: draftText ?? "", + fontSize: isDesktopScreen ? 12 : 14, ); } else if (lastMsg != null) { if (lastMessageBuilder != null && @@ -63,6 +68,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { return lastMessageBuilder!(lastMsg, groupAtInfoList)!; } return TIMUIKitLastMsg( + fontSize: isDesktopScreen ? 12 : 14, groupAtInfoList: groupAtInfoList, lastMsg: lastMsg, context: context, @@ -90,7 +96,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { } else if (lastMsg != null) { return Text(TimeAgo().getTimeStringForChat(lastMsg!.timestamp as int), style: TextStyle( - fontSize: 12, + fontSize: 11, color: theme.conversationItemTitmeTextColor, )); } @@ -102,12 +108,10 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Container( padding: const EdgeInsets.only(top: 6, bottom: 6, left: 16, right: 16), decoration: BoxDecoration( - color: isPined - ? theme.conversationItemPinedBgColor - : theme.conversationItemBgColor, border: Border( bottom: BorderSide( color: theme.conversationItemBorderColor ?? @@ -122,8 +126,8 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { Container( padding: const EdgeInsets.only(top: 0, bottom: 2, right: 0), child: SizedBox( - width: 44, - height: 44, + width: isDesktopScreen ? 40 : 44, + height: isDesktopScreen ? 40 : 44, child: Stack( fit: StackFit.expand, clipBehavior: Clip.none, @@ -151,7 +155,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { Expanded( child: Container( height: 60, - margin: const EdgeInsets.only(left: 12), + margin: EdgeInsets.only(left: isDesktopScreen ? 10 : 12), padding: const EdgeInsets.only(top: 0, bottom: 0), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -169,7 +173,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { style: TextStyle( height: 1, color: theme.conversationItemTitleTextColor, - fontSize: 18, + fontSize: isDesktopScreen ? 14 : 18, fontWeight: FontWeight.w400, ), )), @@ -190,7 +194,7 @@ class TIMUIKitConversationItem extends TIMUIKitStatelessWidget { child: Icon( Icons.notifications_off, color: theme.conversationItemNoNotificationIconColor, - size: 16.0, + size: isDesktopScreen ? 14 : 16.0, ), ) ], diff --git a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart index f79e6eb..09a335a 100644 --- a/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart +++ b/lib/ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg.dart @@ -13,12 +13,14 @@ class TIMUIKitLastMsg extends StatefulWidget { final V2TimMessage? lastMsg; final List groupAtInfoList; final BuildContext context; + final double fontSize; const TIMUIKitLastMsg( {Key? key, this.lastMsg, required this.groupAtInfoList, - required this.context}) + required this.context, + this.fontSize = 14.0}) : super(key: key); @override @@ -46,11 +48,11 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { void _getMsgElem() async { final isRevokedMessage = widget.lastMsg!.status == 6; if (isRevokedMessage) { - final isSelf = widget.lastMsg!.isSelf ?? false; + final isSelf = widget.lastMsg!.isSelf ?? true; final option1 = isSelf ? TIM_t("您") : widget.lastMsg!.nickName ?? widget.lastMsg?.sender; - if(mounted){ + if (mounted) { setState(() { groupTipsAbstractText = TIM_t_para( "{{option1}}撤回了一条消息", "$option1撤回了一条消息")(option1: option1); @@ -58,7 +60,7 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { } } else { final newText = await _getLastMsgShowText(widget.lastMsg, widget.context); - if(mounted){ + if (mounted) { setState(() { groupTipsAbstractText = newText; }); @@ -75,7 +77,7 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { case MessageElemType.V2TIM_ELEM_TYPE_SOUND: return TIM_t("[语音]"); case MessageElemType.V2TIM_ELEM_TYPE_TEXT: - return widget.lastMsg?.textElem?.text ?? ""; + return (widget.lastMsg?.textElem?.text)?.trim() ?? ""; case MessageElemType.V2TIM_ELEM_TYPE_FACE: return TIM_t("[表情]"); case MessageElemType.V2TIM_ELEM_TYPE_FILE: @@ -134,14 +136,16 @@ class _TIMUIKitLastMsgState extends TIMUIKitState { ), if (widget.groupAtInfoList.isNotEmpty) Text(_getAtMessage(), - style: TextStyle(color: theme.cautionColor, fontSize: 14)), + style: TextStyle( + color: theme.cautionColor, fontSize: widget.fontSize)), Expanded( child: Text( groupTipsAbstractText, softWrap: true, maxLines: 1, overflow: TextOverflow.ellipsis, - style: TextStyle(height: 1, color: theme.weakTextColor, fontSize: 14), + style: TextStyle( + height: 1, color: theme.weakTextColor, fontSize: widget.fontSize), )), ]); } diff --git a/lib/ui/views/TIMUIKitGroup/tim_uikit_group.dart b/lib/ui/views/TIMUIKitGroup/tim_uikit_group.dart index eb04886..e58a9f9 100644 --- a/lib/ui/views/TIMUIKitGroup/tim_uikit_group.dart +++ b/lib/ui/views/TIMUIKitGroup/tim_uikit_group.dart @@ -1,7 +1,8 @@ -import 'package:azlistview/azlistview.dart'; +import 'package:azlistview_all_platforms/azlistview_all_platforms.dart'; import 'package:flutter/material.dart'; import 'package:lpinyin/lpinyin.dart'; import 'package:provider/provider.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/listener_model/tui_group_listener_model.dart'; @@ -17,7 +18,8 @@ typedef GroupItemBuilder = Widget Function( BuildContext context, V2TimGroupInfo groupInfo); class TIMUIKitGroup extends StatefulWidget { - final void Function(V2TimGroupInfo groupInfo)? onTapItem; + final void Function(V2TimGroupInfo groupInfo, V2TimConversation conversation)? + onTapItem; final Widget Function(BuildContext context)? emptyBuilder; final GroupItemBuilder? itemBuilder; @@ -68,44 +70,67 @@ class _TIMUIKitGroupState extends TIMUIKitState { final theme = Provider.of(context).theme; final showName = groupInfo.groupName ?? groupInfo.groupID; final faceUrl = groupInfo.faceUrl ?? ""; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Container( - padding: const EdgeInsets.only(top: 10, left: 16), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: theme.weakDividerColor ?? CommonColor.weakDividerColor))), - child: InkWell( - onTap: (() { - if (widget.onTapItem != null) { - widget.onTapItem!(groupInfo); - } - }), - child: Row( - children: [ - Container( - padding: const EdgeInsets.only(bottom: 12), - margin: const EdgeInsets.only(right: 12), - child: SizedBox( - height: 40, - width: 40, - child: Avatar( - faceUrl: faceUrl, - showName: showName, - type: 2, + child: Material( + color: isDesktopScreen ? theme.wideBackgroundColor : null, + child: InkWell( + onTap: (() async { + if (widget.onTapItem != null) { + V2TimConversation conversation = V2TimConversation( + conversationID: "group_${groupInfo.groupID}", + groupID: groupInfo.groupID, + type: 2, + showName: groupInfo.groupName, + groupType: groupInfo.groupType, + faceUrl: groupInfo.faceUrl, + ); + final res = await TencentImSDKPlugin + .v2TIMManager.v2ConversationManager + .getConversation( + conversationID: "group_${groupInfo.groupID}"); + if (res.code == 0 && res.data != null) { + conversation = res.data!; + } + widget.onTapItem!(groupInfo, conversation); + } + }), + child: Container( + padding: const EdgeInsets.only(top: 10, left: 16), + child: Row( + children: [ + Container( + padding: const EdgeInsets.only(bottom: 12), + margin: const EdgeInsets.only(right: 12), + child: SizedBox( + height: isDesktopScreen ? 30 : 40, + width: isDesktopScreen ? 30 : 40, + child: Avatar( + faceUrl: faceUrl, + showName: showName, + type: 2, + ), + ), ), - ), + Expanded( + child: Container( + alignment: Alignment.centerLeft, + padding: const EdgeInsets.only(top: 10, bottom: 20), + child: Text( + showName, + style: TextStyle( + color: Colors.black, fontSize: isDesktopScreen ? 14 : 18), + ), + )) + ], ), - Expanded( - child: Container( - alignment: Alignment.centerLeft, - padding: const EdgeInsets.only(top: 10, bottom: 20), - child: Text( - showName, - style: const TextStyle(color: Colors.black, fontSize: 18), - ), - )) - ], + ), ), ), ); diff --git a/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart b/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart index 69bf2bb..63850cd 100644 --- a/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart +++ b/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list.dart @@ -6,6 +6,7 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_glo import 'package:tencent_cloud_chat_uikit/data_services/group/group_services.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; @@ -74,7 +75,7 @@ class TIMUIKitGroupApplicationListState } String _getRequestMessage() { - String option2 = applicationInfo.requestMsg!; + String option2 = applicationInfo.requestMsg ?? ""; return TIM_t_para("验证消息: {{option2}}", "验证消息: $option2")( option2: option2); } @@ -227,8 +228,10 @@ class TIMUIKitGroupApplicationListState return MultiProvider( providers: [ChangeNotifierProvider.value(value: model)], builder: (context, w) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Container( - decoration: BoxDecoration(color: theme.weakBackgroundColor), + decoration: isDesktopScreen ? null : BoxDecoration(color: theme.weakBackgroundColor), child: ListView.builder( shrinkWrap: true, itemCount: groupApplicationList.length, diff --git a/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list_item.dart b/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list_item.dart index 749474e..acd0060 100644 --- a/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list_item.dart +++ b/lib/ui/views/TIMUIKitGroup/tim_uikit_group_application_list_item.dart @@ -27,10 +27,6 @@ class TIMUIKitGroupApplicationListItemState extends TIMUIKitState { ApplicationStatus applicationStatus = ApplicationStatus.none; - @override - void initState() { - super.initState(); - } String _getUserName() { if (widget.applicationInfo.fromUserNickName != null && diff --git a/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_add_group_member.dart b/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_add_group_member.dart index e89bf65..583a8fc 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_add_group_member.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_add_group_member.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; - import 'package:tencent_cloud_chat_uikit/ui/widgets/contact_list.dart'; +GlobalKey<_AddGroupMemberPageState> addGroupMemberKey = GlobalKey(); + class AddGroupMemberPage extends StatefulWidget { final TUIGroupProfileModel model; @@ -17,56 +19,66 @@ class AddGroupMemberPage extends StatefulWidget { } class _AddGroupMemberPageState extends TIMUIKitState { - List selectedContacter = []; + List selectedContacts = []; + + void submitAdd() async { + if (selectedContacts.isNotEmpty) { + final userIDs = selectedContacts.map((e) => e.userID).toList(); + await widget.model.inviteUserToGroup(userIDs); + Navigator.pop(context); + } + } @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - return Scaffold( - appBar: AppBar( - title: Text( - TIM_t("添加群成员"), - style: const TextStyle(color: Colors.white, fontSize: 17), - ), - actions: [ - TextButton( - onPressed: () async { - if (selectedContacter.isNotEmpty) { - final userIDs = - selectedContacter.map((e) => e.userID).toList(); - await widget.model.inviteUserToGroup(userIDs); - Navigator.pop(context); - } - }, - child: Text( - TIM_t("确定"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, - ), + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: ContactList( + bgColor: theme.wideBackgroundColor, + groupMemberList: widget.model.groupMemberList, + contactList: widget.model.contactList, + isCanSelectMemberItem: true, + onSelectedMemberItemChange: (selectedMember) { + selectedContacts = selectedMember; + }, + ), + ), + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("添加群成员"), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), ), - ) - ], - shadowColor: theme.weakDividerColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, - )), - body: ContactList( - groupMemberList: widget.model.groupMemberList, - contactList: widget.model.contactList, - isCanSelectMemberItem: true, - onSelectedMemberItemChange: (selectedMember) { - selectedContacter = selectedMember; - }, - )); + actions: [ + TextButton( + onPressed: () async { + submitAdd(); + }, + child: Text( + TIM_t("确定"), + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 16, + ), + ), + ) + ], + shadowColor: theme.weakDividerColor, + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + )), + body: ContactList( + groupMemberList: widget.model.groupMemberList, + contactList: widget.model.contactList, + isCanSelectMemberItem: true, + onSelectedMemberItemChange: (selectedMember) { + selectedContacts = selectedMember; + }, + ))); } } diff --git a/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_delete_group_member.dart b/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_delete_group_member.dart index a23b7f7..2e693e4 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_delete_group_member.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_delete_group_member.dart @@ -1,13 +1,15 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; - import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.dart'; +GlobalKey<_DeleteGroupMemberPageState> deleteGroupMemberKey = GlobalKey(); + class DeleteGroupMemberPage extends StatefulWidget { final TUIGroupProfileModel model; @@ -67,56 +69,65 @@ class _DeleteGroupMemberPageState extends TIMUIKitState { []; } + void submitDelete() async { + if (selectedGroupMember.isNotEmpty) { + final userIDs = selectedGroupMember.map((e) => e.userID).toList(); + widget.model.kickOffMember(userIDs); + Navigator.pop(context); + } + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - return Scaffold( - appBar: AppBar( - title: Text( - TIM_t("删除群成员"), - style: const TextStyle(color: Colors.white, fontSize: 17), - ), - actions: [ - TextButton( - onPressed: () async { - if (selectedGroupMember.isNotEmpty) { - final userIDs = - selectedGroupMember.map((e) => e.userID).toList(); - widget.model.kickOffMember(userIDs); - Navigator.pop(context); - } - }, - child: Text( - TIM_t("确定"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, - ), + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: GroupProfileMemberList( + memberList: + handleRole(searchMemberList ?? widget.model.groupMemberList), + canSelectMember: true, + canSlideDelete: false, + onSelectedMemberChange: (selectedMember) { + selectedGroupMember = selectedMember; + }, + touchBottomCallBack: () {}, + ), + ), + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("删除群成员"), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), ), - ) - ], - shadowColor: theme.weakBackgroundColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, - )), - body: GroupProfileMemberList( - memberList: - handleRole(searchMemberList ?? widget.model.groupMemberList), - canSelectMember: true, - canSlideDelete: false, - onSelectedMemberChange: (selectedMember) { - selectedGroupMember = selectedMember; - }, - touchBottomCallBack: () {}, - )); + actions: [ + TextButton( + onPressed: submitDelete, + child: Text( + TIM_t("确定"), + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 16, + ), + ), + ) + ], + shadowColor: theme.weakBackgroundColor, + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + )), + body: GroupProfileMemberList( + memberList: + handleRole(searchMemberList ?? widget.model.groupMemberList), + canSelectMember: true, + canSlideDelete: false, + onSelectedMemberChange: (selectedMember) { + selectedGroupMember = selectedMember; + }, + touchBottomCallBack: () {}, + ))); } } diff --git a/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_group_member_list.dart b/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_group_member_list.dart index 0aaab63..a397b31 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_group_member_list.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/group_member/tui_group_member_list.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; @@ -81,6 +82,8 @@ class GroupProfileMemberListPageState @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop; return MultiProvider( providers: [ ChangeNotifierProvider.value(value: widget.model), @@ -90,24 +93,36 @@ class GroupProfileMemberListPageState Provider.of(context); String option1 = groupProfileModel.groupInfo?.memberCount.toString() ?? widget.memberList.length.toString(); + if(isDesktopScreen){ + return GroupProfileMemberList( + customTopArea: PlatformUtils().isWeb + ? null + : GroupMemberSearchTextField( + onTextChange: (text) => + handleSearchGroupMembers(text, context), + ), + memberList: searchMemberList ?? groupProfileModel.groupMemberList, + removeMember: _kickedOffMember, + touchBottomCallBack: () {}, + onTapMemberItem: (friendInfo, details) { + if (widget.model.onClickUser != null) { + widget.model.onClickUser!(friendInfo.userID, details); + } + }, + ); + } return Scaffold( appBar: AppBar( title: Text( TIM_t_para("群成员({{option1}}人)", "群成员($option1人)")( option1: option1), - style: const TextStyle(color: Colors.white, fontSize: 17), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), ), shadowColor: theme.weakBackgroundColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, )), body: GroupProfileMemberList( customTopArea: PlatformUtils().isWeb @@ -119,12 +134,13 @@ class GroupProfileMemberListPageState memberList: searchMemberList ?? groupProfileModel.groupMemberList, removeMember: _kickedOffMember, touchBottomCallBack: () {}, - onTapMemberItem: (friendInfo) { + onTapMemberItem: (friendInfo, details) { if (widget.model.onClickUser != null) { - widget.model.onClickUser!(friendInfo.userID); + widget.model.onClickUser!(friendInfo.userID, details); } }, - )); + ) + ); }, ); } diff --git a/lib/ui/views/TIMUIKitGroupProfile/tim_uikit_group_profile.dart b/lib/ui/views/TIMUIKitGroupProfile/tim_uikit_group_profile.dart index 751c440..d04fb83 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/tim_uikit_group_profile.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/tim_uikit_group_profile.dart @@ -8,6 +8,7 @@ import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_grou import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_profile_widget.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_profile_widget.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_button_area.dart'; @@ -54,7 +55,7 @@ class TIMUIKitGroupProfile extends StatefulWidget { /// The callback after user clicking a user, /// you may navigating to the specific profile page, or anywhere you want. - final Function(String userID)? onClickUser; + final Function(String userID, TapDownDetails? tapDetails)? onClickUser; const TIMUIKitGroupProfile( {Key? key, @@ -96,7 +97,7 @@ class _TIMUIKitGroupProfileState extends TIMUIKitState { @override void didUpdateWidget(covariant TIMUIKitGroupProfile oldWidget) { super.didUpdateWidget(oldWidget); - if(oldWidget.groupID != widget.groupID){ + if (oldWidget.groupID != widget.groupID) { model.loadData(widget.groupID); } } @@ -135,6 +136,8 @@ class _TIMUIKitGroupProfileState extends TIMUIKitState { model.lifeCycle = widget.lifeCycle; final V2TimGroupInfo? groupInfo = model.groupInfo; final memberList = model.groupMemberList; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (groupInfo == null) { return Center( child: LoadingAnimationWidget.staggeredDotsWave( @@ -170,7 +173,10 @@ class _TIMUIKitGroupProfileState extends TIMUIKitState { Widget groupProfilePage({required Widget child}) { return SingleChildScrollView( child: Container( - color: widget.backGroundColor ?? theme.weakBackgroundColor, + color: widget.backGroundColor ?? + (isDesktopScreen + ? theme.wideBackgroundColor + : theme.weakBackgroundColor), child: child, ), ); @@ -205,6 +211,7 @@ class _TIMUIKitGroupProfileState extends TIMUIKitState { ? customBuilder?.detailCard!( groupInfo, model.setGroupName) : TIMUIKitGroupProfileWidget.detailCard( + isHavePermission: isAdmin || isGroupOwner, groupInfo: groupInfo))!; case GroupProfileWidgetEnum.memberListTile: return (customBuilder?.memberListTile != null @@ -216,7 +223,8 @@ class _TIMUIKitGroupProfileState extends TIMUIKitState { groupInfo.notification ?? "", toDefaultNoticePage, model.setGroupNotification) - : TIMUIKitGroupProfileWidget.groupNotification())!; + : TIMUIKitGroupProfileWidget.groupNotification( + isHavePermission: isAdmin || isGroupOwner))!; case GroupProfileWidgetEnum.groupManage: if (isAdmin || isGroupOwner) { return (customBuilder?.groupManage != null @@ -232,14 +240,15 @@ class _TIMUIKitGroupProfileState extends TIMUIKitState { case GroupProfileWidgetEnum.operationDivider: return (customBuilder?.operationDivider != null ? customBuilder?.operationDivider!() - : TIMUIKitGroupProfileWidget.operationDivider())!; + : TIMUIKitGroupProfileWidget.operationDivider(theme))!; case GroupProfileWidgetEnum.groupTypeBar: return (customBuilder?.groupTypeBar != null ? customBuilder?.groupTypeBar!(groupInfo.groupType) : TIMUIKitGroupProfileWidget.groupType())!; case GroupProfileWidgetEnum.groupJoiningModeBar: final String groupType = groupInfo.groupType; - if (groupType == "Work" || + if (!(isGroupOwner || isAdmin) || + groupType == "Work" || groupType == "Meeting" || groupType == "AVChatRoom") { return Container(); diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart index ccfbaee..9af7999 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart @@ -4,6 +4,8 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; class GroupMemberSearchTextField extends TIMUIKitStatelessWidget { @@ -14,13 +16,17 @@ class GroupMemberSearchTextField extends TIMUIKitStatelessWidget { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final FocusNode focusNode = FocusNode(); var debounceFunc = OptimizeUtils.debounce( (text) => onTextChange(text), const Duration(milliseconds: 300)); + return Container( color: Colors.white, child: Column(children: [ - Container( + if(!isDesktopScreen) Container( decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(5.0)), border: Border.all(color: theme.weakBackgroundColor!, width: 12)), @@ -32,6 +38,16 @@ class GroupMemberSearchTextField extends TIMUIKitStatelessWidget { ), ), ), + if(isDesktopScreen) TIMUIKitSearchInput(prefixIcon: Icon( + Icons.search, + size: 16, + color: hexToColor("979797"), + ), + onChange: (text){ + focusNode.requestFocus(); + debounceFunc(text); + }, focusNode: focusNode, + ), Divider( thickness: 1, indent: 74, diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_profile_widget.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_profile_widget.dart index 291ee98..4753ad5 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_profile_widget.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_profile_widget.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_search_msg.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_add_opt.dart'; @@ -14,11 +15,13 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/t class TIMUIKitGroupProfileWidget { static Widget detailCard( {required V2TimGroupInfo groupInfo, + bool isHavePermission = false, /// You can deal with updating group name manually, or UIKIt do it automatically. Function(String updateGroupName)? updateGroupName}) { return GroupProfileDetailCard( groupInfo: groupInfo, + isHavePermission: isHavePermission, updateGroupName: updateGroupName, ); } @@ -27,21 +30,27 @@ class TIMUIKitGroupProfileWidget { return GroupMemberTile(); } - static Widget groupNotification() { - return GroupProfileNotification(); + static Widget groupNotification({ + bool isHavePermission = false, + }) { + return GroupProfileNotification( + isHavePermission: isHavePermission, + ); } static Widget groupManage() { - return GroupProfileGroupManage(); + return const GroupProfileGroupManage(); } static Widget searchMessage(Function(V2TimConversation?) onJumpToSearch) { return GroupProfileGroupSearch(onJumpToSearch: onJumpToSearch); } - static Widget operationDivider() { - return const SizedBox( - height: 10, + static Widget operationDivider(TUITheme theme) { + final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop; + return Container( + color: theme.weakDividerColor, + height: isDesktopScreen ? 1 : 10, ); } @@ -54,7 +63,7 @@ class TIMUIKitGroupProfileWidget { } static Widget nameCard() { - return GroupProfileNameCard(); + return const GroupProfileNameCard(); } static Widget messageDisturb() { diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_search_msg.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_search_msg.dart index 23f1033..e70f63a 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_search_msg.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_search_msg.dart @@ -39,7 +39,8 @@ class GroupProfileGroupSearch extends TIMUIKitStatelessWidget { } }, child: Container( - padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12), + padding: const EdgeInsets.symmetric( + vertical: 14, horizontal: 16), decoration: BoxDecoration( color: Colors.white, border: Border( diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_add_opt.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_add_opt.dart index 5484a73..816ac67 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_add_opt.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_add_opt.dart @@ -1,5 +1,11 @@ +import 'dart:math'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; @@ -16,6 +22,8 @@ class GroupProfileAddOpt extends TIMUIKitStatelessWidget { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; final model = Provider.of(context); + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; String addOpt = TIM_t("未知"); @@ -40,65 +48,87 @@ class GroupProfileAddOpt extends TIMUIKitStatelessWidget { _handleActionTap(int addOpt) async { model.setGroupAddOpt(addOpt).then((res) {}); - Navigator.pop( - context, - "cancel", - ); } return Container( - padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: Colors.white, - border: Border( + border: isDesktopScreen ? null : Border( bottom: BorderSide( color: theme.weakDividerColor ?? CommonColor.weakDividerColor))), child: InkWell( - onTap: () async { - showCupertinoModalPopup( - context: context, - builder: (BuildContext context) { - return CupertinoActionSheet( - title: Text(TIM_t("加群方式")), - cancelButton: CupertinoActionSheetAction( - onPressed: () { - Navigator.pop( - context, - "cancel", - ); - }, - child: Text(TIM_t("取消")), - isDefaultAction: false, - ), - actions: actionList - .map((e) => CupertinoActionSheetAction( - onPressed: () { - _handleActionTap(e["id"] as int); - }, - child: Text( - e["label"] as String, - style: TextStyle(color: theme.primaryColor), - ), - isDefaultAction: false, - )) - .toList(), - ); - }, - ); + onTapDown: (details) async { + if(isDesktopScreen){ + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.groupAddOpt, + isDarkBackground: false, + borderRadius: const BorderRadius.all(Radius.circular(4)), + context: context, + offset: Offset(min(details.globalPosition.dx, + MediaQuery.of(context).size.width - 186), details.globalPosition.dy), + child: (onClose) => TUIKitColumnMenu( + data: [ + ...actionList + .map((e){ + return ColumnMenuItem(label: e["label"] as String, onClick: (){ + _handleActionTap(e["id"] as int); + onClose(); + }); + }), + ], + ) + ); + }else{ + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) { + return CupertinoActionSheet( + title: Text(TIM_t("加群方式")), + cancelButton: CupertinoActionSheetAction( + onPressed: () { + Navigator.pop( + context, + "cancel", + ); + }, + child: Text(TIM_t("取消")), + isDefaultAction: false, + ), + actions: actionList + .map((e) => CupertinoActionSheetAction( + onPressed: () { + _handleActionTap(e["id"] as int); + Navigator.pop( + context, + "cancel", + ); + }, + child: Text( + e["label"] as String, + style: TextStyle(color: theme.primaryColor), + ), + isDefaultAction: false, + )) + .toList(), + ); + }, + ); + } }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( TIM_t("加群方式"), - style: TextStyle(fontSize: 16, color: theme.darkTextColor), + style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor), ), Row( children: [ Text( addOpt, - style: const TextStyle(fontSize: 16, color: Colors.black), + style: TextStyle(fontSize: isDesktopScreen ? 14 : 16, color: Colors.black), ), Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor) ], diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_button_area.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_button_area.dart index 16d00b5..88f5bfd 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_button_area.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_button_area.dart @@ -3,10 +3,13 @@ import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/controller/tim_uikit_chat_controller.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; class GroupProfileButtonArea extends TIMUIKitStatelessWidget { final String groupID; @@ -20,164 +23,268 @@ class GroupProfileButtonArea extends TIMUIKitStatelessWidget { : super(key: key); final _operationList = [ - {"label": TIM_t("清空聊天记录"), "id": "clearHistory"}, + {"label": TIM_t("清空消息"), "id": "clearHistory"}, {"label": TIM_t("转让群主"), "id": "transimitOwner"}, - {"label": TIM_t("删除并退出"), "id": "quitGroup"}, - {"label": TIM_t("解散该群"), "id": "dismissGroup"} + {"label": TIM_t("退出群组"), "id": "quitGroup"}, + {"label": TIM_t("解散群组"), "id": "dismissGroup"} ]; _clearHistory(BuildContext context, theme) async { - showCupertinoModalPopup( - context: context, - builder: (BuildContext context) { - return CupertinoActionSheet( - cancelButton: CupertinoActionSheetAction( - onPressed: () { - Navigator.pop( - context, - ); - }, - child: Text(TIM_t("取消")), - isDefaultAction: false, - ), - actions: [ - CupertinoActionSheetAction( - onPressed: () async { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + if (isDesktopScreen) { + TUIKitWidePopup.showSecondaryConfirmDialog( + operationKey: TUIKitWideModalOperationKey.confirmClearChatHistory, + context: context, + text: TIM_t("清空聊天记录"), + theme: theme, + onCancel: () {}, + onConfirm: () async { + if (PlatformUtils().isWeb) { + final res = await sdkInstance + .getConversationManager() + .deleteConversation(conversationID: "group_$groupID"); + if (res.code == 0) { + _timuiKitChatController.clearHistory(groupID); + } + } else { + final res = await sdkInstance + .getMessageManager() + .clearGroupHistoryMessage(groupID: groupID); + if (res.code == 0) { + _timuiKitChatController.clearHistory(groupID); + } + } + }); + } else { + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) { + return CupertinoActionSheet( + cancelButton: CupertinoActionSheetAction( + onPressed: () { Navigator.pop( context, ); - if (PlatformUtils().isWeb) { - final res = await sdkInstance - .getConversationManager() - .deleteConversation(conversationID: "group_$groupID"); - if (res.code == 0) { - _timuiKitChatController.clearHistory(groupID); - } - } else { - final res = await sdkInstance - .getMessageManager() - .clearGroupHistoryMessage(groupID: groupID); - if (res.code == 0) { - _timuiKitChatController.clearHistory(groupID); - } - } }, - child: Text( - TIM_t("清空聊天记录"), - style: TextStyle(color: theme.cautionColor), - ), + child: Text(TIM_t("取消")), isDefaultAction: false, - ) - ], - ); - }, - ); + ), + actions: [ + CupertinoActionSheetAction( + onPressed: () async { + Navigator.pop( + context, + ); + if (PlatformUtils().isWeb) { + final res = await sdkInstance + .getConversationManager() + .deleteConversation(conversationID: "group_$groupID"); + if (res.code == 0) { + _timuiKitChatController.clearHistory(groupID); + } + } else { + final res = await sdkInstance + .getMessageManager() + .clearGroupHistoryMessage(groupID: groupID); + if (res.code == 0) { + _timuiKitChatController.clearHistory(groupID); + } + } + }, + child: Text( + TIM_t("清空聊天记录"), + style: TextStyle(color: theme.cautionColor), + ), + isDefaultAction: false, + ) + ], + ); + }, + ); + } } - _quitGroup(BuildContext context, theme) async { - showCupertinoModalPopup( - context: context, - builder: (BuildContext context) { - return CupertinoActionSheet( - title: Text(TIM_t("退出后不会接收到此群聊消息")), - cancelButton: CupertinoActionSheetAction( - onPressed: () { - Navigator.pop( - context, - ); - }, - child: Text(TIM_t("取消")), - isDefaultAction: false, - ), - actions: [ - CupertinoActionSheetAction( - onPressed: () async { + _quitGroup(BuildContext context, TUITheme theme) async { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + if (isDesktopScreen) { + TUIKitWidePopup.showSecondaryConfirmDialog( + operationKey: TUIKitWideModalOperationKey.confirmExitGroup, + context: context, + text: TIM_t("退出后不会接收到此群聊消息"), + theme: theme, + onCancel: () {}, + onConfirm: () async { + final res = await sdkInstance.quitGroup(groupID: groupID); + if (res.code == 0) { + final deleteConvRes = await sdkInstance + .getConversationManager() + .deleteConversation(conversationID: "group_$groupID"); + if (deleteConvRes.code == 0) { + model.lifeCycle?.didLeaveGroup(); + } + } + }); + } else { + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) { + return CupertinoActionSheet( + title: Text(TIM_t("退出后不会接收到此群聊消息")), + cancelButton: CupertinoActionSheetAction( + onPressed: () { Navigator.pop( context, ); - final res = await sdkInstance.quitGroup(groupID: groupID); - if (res.code == 0) { - final deleteConvRes = await sdkInstance - .getConversationManager() - .deleteConversation(conversationID: "group_$groupID"); - if (deleteConvRes.code == 0) { - model.lifeCycle?.didLeaveGroup(); - } - } }, - child: Text( - TIM_t("确定"), - style: TextStyle(color: theme.cautionColor), - ), + child: Text(TIM_t("取消")), isDefaultAction: false, - ) - ], - ); - }, - ); + ), + actions: [ + CupertinoActionSheetAction( + onPressed: () async { + Navigator.pop( + context, + ); + final res = await sdkInstance.quitGroup(groupID: groupID); + if (res.code == 0) { + final deleteConvRes = await sdkInstance + .getConversationManager() + .deleteConversation(conversationID: "group_$groupID"); + if (deleteConvRes.code == 0) { + model.lifeCycle?.didLeaveGroup(); + } + } + }, + child: Text( + TIM_t("确定"), + style: TextStyle(color: theme.cautionColor), + ), + isDefaultAction: false, + ) + ], + ); + }, + ); + } } _dismissGroup(BuildContext context, theme) async { - showCupertinoModalPopup( - context: context, - builder: (BuildContext context) { - return CupertinoActionSheet( - title: Text(TIM_t("解散后不会接收到此群聊消息")), - cancelButton: CupertinoActionSheetAction( - onPressed: () { - Navigator.pop( - context, - ); - }, - child: Text(TIM_t("取消")), - isDefaultAction: false, - ), - actions: [ - CupertinoActionSheetAction( - onPressed: () async { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + if (isDesktopScreen) { + TUIKitWidePopup.showSecondaryConfirmDialog( + operationKey: TUIKitWideModalOperationKey.confirmDisbandGroup, + context: context, + text: TIM_t("解散后不会接收到此群聊消息"), + theme: theme, + onCancel: () {}, + onConfirm: () async { + final res = await sdkInstance.dismissGroup(groupID: groupID); + if (res.code == 0) { + await sdkInstance + .getConversationManager() + .deleteConversation(conversationID: "group_$groupID"); + model.lifeCycle?.didLeaveGroup(); + } + }); + } else { + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) { + return CupertinoActionSheet( + title: Text(TIM_t("解散后不会接收到此群聊消息")), + cancelButton: CupertinoActionSheetAction( + onPressed: () { Navigator.pop( context, ); - final res = await sdkInstance.dismissGroup(groupID: groupID); - if (res.code == 0) { - await sdkInstance - .getConversationManager() - .deleteConversation(conversationID: "group_$groupID"); - model.lifeCycle?.didLeaveGroup(); - } }, - child: Text( - TIM_t("确定"), - style: TextStyle(color: theme.cautionColor), - ), + child: Text(TIM_t("取消")), isDefaultAction: false, - ) - ], - ); - }, - ); + ), + actions: [ + CupertinoActionSheetAction( + onPressed: () async { + Navigator.pop( + context, + ); + final res = await sdkInstance.dismissGroup(groupID: groupID); + if (res.code == 0) { + await sdkInstance + .getConversationManager() + .deleteConversation(conversationID: "group_$groupID"); + model.lifeCycle?.didLeaveGroup(); + } + }, + child: Text( + TIM_t("确定"), + style: TextStyle(color: theme.cautionColor), + ), + isDefaultAction: false, + ) + ], + ); + }, + ); + } } - _transimitOwner(BuildContext context, String groupID) async { - List? selectedMember = await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SelectTransimitOwner( + _transmitOwner(BuildContext context, String groupID) async { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + if (isDesktopScreen) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.setAdmins, + context: context, + title: TIM_t("转让群主"), + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.8, + onSubmit: () { + selectNewGroupOwnerKey.currentState?.onSubmit(); + }, + child: (onClose) => SelectNewGroupOwner( model: model, + key: selectNewGroupOwnerKey, groupID: groupID, + onSelectedMember: (selectedMember) async { + if (selectedMember.isNotEmpty) { + final userID = selectedMember.first.userID; + await sdkInstance + .getGroupManager() + .transferGroupOwner(groupID: groupID, userID: userID); + } + }, ), - ), - ); - if (selectedMember != null) { - final userID = selectedMember.first.userID; - await sdkInstance - .getGroupManager() - .transferGroupOwner(groupID: groupID, userID: userID); + ); + } else { + List? selectedMember = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SelectNewGroupOwner( + model: model, + groupID: groupID, + ), + ), + ); + if (selectedMember != null) { + final userID = selectedMember.first.userID; + await sdkInstance + .getGroupManager() + .transferGroupOwner(groupID: groupID, userID: userID); + } } } List _renderGroupOperation( BuildContext context, TUITheme theme, bool isOwner, String groupType) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return _operationList .where((element) { if (!isOwner) { @@ -194,33 +301,50 @@ class GroupProfileButtonArea extends TIMUIKitStatelessWidget { return true; } }) - .map((e) => InkWell( - onTap: () { - if (e["id"]! == "clearHistory") { - _clearHistory(context, theme); - } else if (e["id"] == "quitGroup") { - _quitGroup(context, theme); - } else if (e["id"] == "dismissGroup") { - _dismissGroup(context, theme); - } else if (e["id"] == "transimitOwner") { - _transimitOwner(context, groupID); - } - }, - child: Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric(vertical: 15), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), + .map((e) => isDesktopScreen + ? OutlinedButton( + onPressed: () { + if (e["id"]! == "clearHistory") { + _clearHistory(context, theme); + } else if (e["id"] == "quitGroup") { + _quitGroup(context, theme); + } else if (e["id"] == "dismissGroup") { + _dismissGroup(context, theme); + } else if (e["id"] == "transimitOwner") { + _transmitOwner(context, groupID); + } + }, child: Text( e["label"]!, - style: TextStyle(color: theme.cautionColor, fontSize: 17), + style: TextStyle(color: theme.cautionColor), + )) + : InkWell( + onTap: () { + if (e["id"]! == "clearHistory") { + _clearHistory(context, theme); + } else if (e["id"] == "quitGroup") { + _quitGroup(context, theme); + } else if (e["id"] == "dismissGroup") { + _dismissGroup(context, theme); + } else if (e["id"] == "transimitOwner") { + _transmitOwner(context, groupID); + } + }, + child: Container( + alignment: Alignment.center, + padding: const EdgeInsets.symmetric(vertical: 15), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), + child: Text( + e["label"]!, + style: TextStyle(color: theme.cautionColor, fontSize: 17), + ), ), - ), - )) + )) .toList(); } @@ -228,6 +352,25 @@ class GroupProfileButtonArea extends TIMUIKitStatelessWidget { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; final groupInfo = model.groupInfo; + + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + if (isDesktopScreen) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Wrap( + spacing: 28, + children: [ + ..._renderGroupOperation( + context, + theme, + groupInfo?.owner == coreInstance.loginUserInfo?.userID, + groupInfo?.groupType ?? "") + ], + ), + ); + } + return Column( children: [ ..._renderGroupOperation( diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_detail_card.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_detail_card.dart index 9b4c0db..8bf8458 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_detail_card.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_detail_card.dart @@ -1,8 +1,12 @@ +import 'dart:math'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/text_input_bottom_sheet.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; @@ -13,9 +17,13 @@ class GroupProfileDetailCard extends TIMUIKitStatelessWidget { final V2TimGroupInfo groupInfo; final void Function(String groupName)? updateGroupName; final TextEditingController controller = TextEditingController(); + final bool isHavePermission; GroupProfileDetailCard( - {Key? key, required this.groupInfo, this.updateGroupName}) + {Key? key, + required this.groupInfo, + this.isHavePermission = false, + this.updateGroupName}) : super(key: key); @override @@ -25,131 +33,168 @@ class GroupProfileDetailCard extends TIMUIKitStatelessWidget { final faceUrl = groupInfo.faceUrl ?? ""; final groupID = groupInfo.groupID; final showName = groupInfo.groupName ?? groupID; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + return InkWell( - onTap: (() { - showCupertinoModalPopup( - context: context, - builder: (BuildContext context) { - return CupertinoActionSheet( - cancelButton: CupertinoActionSheetAction( - onPressed: () { - Navigator.pop( - context, - ); - }, - child: Text(TIM_t("取消")), - isDefaultAction: false, - ), - actions: [ - CupertinoActionSheetAction( - onPressed: () { - controller.text = groupInfo.groupName ?? ""; - showModalBottomSheet( - isScrollControlled: true, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - context: context, - builder: (context) { - return Container( - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), - topRight: Radius.circular(10.0))), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: const EdgeInsets.symmetric( - vertical: 20), - child: Text(TIM_t("修改群名称")), - ), - Divider( - height: 2, color: theme.weakDividerColor), - Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - TextField( - controller: controller, - decoration: InputDecoration( - border: InputBorder.none, - fillColor: - theme.weakBackgroundColor, - filled: true, - isDense: true, - hintText: ''), - ), - const SizedBox( - height: 10, - ), - Text( - TIM_t("修改群名称"), - style: TextStyle( - fontSize: 13, - color: theme.weakTextColor), - textAlign: TextAlign.left, - ), - const SizedBox( - height: 30, - ), - SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: () { - final text = - controller.text.trim(); - if (updateGroupName != null) { - updateGroupName!(text); - } else { - model.setGroupName(text); - } - Navigator.pop(context); - Navigator.pop(context); - }, - child: Text(TIM_t("确定")), - )), - const SizedBox( - height: 20, - ), - Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context) - .viewInsets - .bottom), - ) - ], - ), - ) - ], - ), - ); - }); + onTapDown: !isHavePermission + ? null + : ((details) { + if (isDesktopScreen) { + TextInputBottomSheet.showTextInputBottomSheet( + context: context, + title: TIM_t("修改群名称"), + initText: showName, + initOffset: Offset( + min(details.globalPosition.dx, + MediaQuery.of(context).size.width - 350), + min(details.globalPosition.dy + 20, + MediaQuery.of(context).size.height - 470)), + onSubmitted: (String newText) async { + final text = newText.trim(); + if (updateGroupName != null) { + updateGroupName!(text); + } else { + model.setGroupName(text); + } }, - child: Text( - TIM_t("修改群名称"), - style: TextStyle(color: theme.primaryColor), - ), - isDefaultAction: false, - ) - ]); - }, - ); - }), + theme: theme); + } else { + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) { + return CupertinoActionSheet( + cancelButton: CupertinoActionSheetAction( + onPressed: () { + Navigator.pop( + context, + ); + }, + child: Text(TIM_t("取消")), + isDefaultAction: false, + ), + actions: [ + CupertinoActionSheetAction( + onPressed: () { + controller.text = groupInfo.groupName ?? ""; + showModalBottomSheet( + isScrollControlled: true, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + context: context, + builder: (context) { + return Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.0), + topRight: Radius.circular(10.0))), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: const EdgeInsets.symmetric( + vertical: 20), + child: Text(TIM_t("修改群名称")), + ), + Divider( + height: 2, + color: theme.weakDividerColor), + Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + TextField( + controller: controller, + decoration: InputDecoration( + border: InputBorder.none, + fillColor: theme + .weakBackgroundColor, + filled: true, + isDense: true, + hintText: ''), + ), + const SizedBox( + height: 10, + ), + Text( + TIM_t("修改群名称"), + style: TextStyle( + fontSize: 13, + color: + theme.weakTextColor), + textAlign: TextAlign.left, + ), + const SizedBox( + height: 30, + ), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () { + final text = controller + .text + .trim(); + if (updateGroupName != + null) { + updateGroupName!( + text); + } else { + model.setGroupName( + text); + } + Navigator.pop(context); + Navigator.pop(context); + }, + child: Text(TIM_t("确定")), + )), + const SizedBox( + height: 20, + ), + Padding( + padding: EdgeInsets.only( + bottom: + MediaQuery.of(context) + .viewInsets + .bottom), + ) + ], + ), + ) + ], + ), + ); + }); + }, + child: Text( + TIM_t("修改群名称"), + style: TextStyle(color: theme.primaryColor), + ), + isDefaultAction: false, + ) + ]); + }, + ); + } + }), child: Container( color: Colors.white, - padding: const EdgeInsets.only(top: 12, bottom: 12, left: 16), + padding: EdgeInsets.only( + top: isDesktopScreen ? 20 : 12, + bottom: isDesktopScreen ? 20 : 12, + right: isDesktopScreen ? 16 : 0, + left: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( - width: 48, - height: 48, + width: isDesktopScreen ? 40 : 48, + height: isDesktopScreen ? 40 : 48, child: Avatar( faceUrl: faceUrl, showName: showName, @@ -162,25 +207,28 @@ class GroupProfileDetailCard extends TIMUIKitStatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( + SelectableText( showName, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.w600), + style: TextStyle( + fontSize: isDesktopScreen ? 15 : 18, + fontWeight: FontWeight.w600), ), - const SizedBox( - height: 8, + SizedBox( + height: isDesktopScreen ? 4 : 8, ), - Text("ID: $groupID", + SelectableText("ID: $groupID", style: TextStyle( - fontSize: 13, color: theme.weakTextColor)) + fontSize: isDesktopScreen ? 13 : 13, + color: theme.weakTextColor)) ], ), ), ), - Icon( - Icons.keyboard_arrow_right, - color: theme.weakTextColor, - ) + if (isHavePermission) + Icon( + Icons.keyboard_arrow_right, + color: theme.weakTextColor, + ) ], ), ), diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_manage.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_manage.dart index dc9919a..625a781 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_manage.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_manage.dart @@ -1,56 +1,95 @@ +import 'dart:math'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slidable_for_tencent_im/flutter_slidable.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/column_menu.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; -import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; - import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; - - import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart'; - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; -class GroupProfileGroupManage extends TIMUIKitStatelessWidget { - GroupProfileGroupManage({Key? key}) : super(key: key); +GlobalKey<_GroupProfileAddAdminState> groupProfileAddAdminKey = GlobalKey(); + +class GroupProfileGroupManage extends StatefulWidget { + const GroupProfileGroupManage({Key? key}) : super(key: key); + + @override + State createState() => GroupProfileGroupManageState(); +} + +class GroupProfileGroupManageState + extends TIMUIKitState { + bool isShowManageBox = false; @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final model = Provider.of(context); - return InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GroupProfileGroupManagePage( - model: model, - ))); - }, - child: Container( - padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - TIM_t("群管理"), - style: TextStyle(fontSize: 16, color: theme.darkTextColor), + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + color: Colors.white, + border: isDesktopScreen + ? null + : Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), + child: Column( + children: [ + InkWell( + onTap: () { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == + DeviceType.Desktop; + if (!isDesktopScreen) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => GroupProfileGroupManagePage( + model: model, + ))); + } else { + setState(() { + isShowManageBox = !isShowManageBox; + }); + } + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + TIM_t("群管理"), + style: TextStyle( + fontSize: isDesktopScreen ? 14 : 16, + color: theme.darkTextColor), + ), + AnimatedRotation( + turns: isShowManageBox ? 0.25 : 0, + duration: const Duration(milliseconds: 200), + child: Icon(Icons.keyboard_arrow_right, + color: theme.weakTextColor), + ) + ], ), - Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor) - ], - ), + ), + if (isShowManageBox) + GroupProfileGroupManagePage( + model: model, + ) + ], ), ); } @@ -59,6 +98,7 @@ class GroupProfileGroupManage extends TIMUIKitStatelessWidget { /// 管理员设置页面 class GroupProfileGroupManagePage extends StatefulWidget { final TUIGroupProfileModel model; + const GroupProfileGroupManagePage({ Key? key, required this.model, @@ -79,7 +119,7 @@ class _GroupProfileGroupManagePageState } void getServerTime() async { - final res = await TencentImSDKPlugin.v2TIMManager.getServerTime(); + final res = await TencentImSDKPlugin.v2TIMManager.getServerTime(); setState(() { serverTime = res.data; }); @@ -98,125 +138,152 @@ class _GroupProfileGroupManagePageState Provider.of(context).groupMemberList; final theme = Provider.of(context).theme; final isAllMuted = widget.model.groupInfo?.isAllMuted ?? false; - return Scaffold( - appBar: AppBar( - title: Text( - TIM_t("群管理"), - style: const TextStyle(color: Colors.white, fontSize: 17), - ), - shadowColor: theme.weakDividerColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, - ), - leading: IconButton( - padding: const EdgeInsets.only(left: 16), - constraints: const BoxConstraints(), - icon: Image.asset( - 'images/arrow_back.png', - package: 'tencent_cloud_chat_uikit', - height: 34, - width: 34, - ), - onPressed: () async { - if (isAllMuted != widget.model.groupInfo?.isAllMuted) { - widget.model.setMuteAll(isAllMuted); - } - Navigator.pop(context); - }, - ), - ), - body: Column( + final bool isAllowMuteMember = + (widget.model.groupInfo?.groupType ?? "") != GroupType.Work; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + Widget managePage() { + return Column( children: [ Container( - padding: const EdgeInsets.only( - top: 12, left: 16, bottom: 12, right: 12), + padding: EdgeInsets.only( + top: 12, + left: isDesktopScreen ? 0 : 16, + bottom: isDesktopScreen ? 0 : 12, + right: isDesktopScreen ? 0 : 12), decoration: BoxDecoration( color: Colors.white, - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), + border: isDesktopScreen + ? null + : Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), child: InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GroupProfileSetManagerPage( - model: widget.model, - ), - )); - }, + onTap: isDesktopScreen + ? null + : () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + GroupProfileSetManagerPage( + model: widget.model, + ), + )); + }, + child: isDesktopScreen + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(TIM_t("群管理员"), + style: TextStyle( + fontSize: 14, + color: theme.darkTextColor)), + ], + ) + : Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(TIM_t("设置管理员"), + style: TextStyle( + fontSize: isDesktopScreen ? 14 : 16, + color: theme.darkTextColor)), + Icon(Icons.keyboard_arrow_right, + color: theme.weakTextColor) + ], + ), + ), + ), + if (isDesktopScreen) + GroupProfileSetManagerPage( + model: widget.model, + ), + if (!isDesktopScreen) + Container( + padding: const EdgeInsets.only( + top: 12, left: 16, bottom: 12, right: 12), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(TIM_t("设置管理员"), - style: TextStyle( - fontSize: 16, color: theme.darkTextColor)), - Icon(Icons.keyboard_arrow_right, - color: theme.weakTextColor) + Text( + TIM_t("全员禁言"), + style: TextStyle( + fontSize: 16, color: theme.darkTextColor), + ), + CupertinoSwitch( + value: isAllMuted, + onChanged: (value) async { + widget.model.setMuteAll(value); + }, + activeColor: theme.primaryColor) ], ), ), - ), - Container( - padding: const EdgeInsets.only( - top: 12, left: 16, bottom: 12, right: 12), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), - child: Row( + if (isDesktopScreen && isAllowMuteMember) + Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - TIM_t("全员禁言"), - style: - TextStyle(fontSize: 16, color: theme.darkTextColor), - ), - CupertinoSwitch( - value: isAllMuted, - onChanged: (value) async { - widget.model.setMuteAll(value); - }, - activeColor: theme.primaryColor) + Text(TIM_t("禁言"), + style: TextStyle( + fontSize: 14, color: theme.darkTextColor)), ], ), - ), - Container( - padding: - const EdgeInsets.symmetric(vertical: 10, horizontal: 16), - color: theme.weakBackgroundColor, - alignment: Alignment.topLeft, - child: Text( - TIM_t("全员禁言开启后,只允许群主和管理员发言。"), - style: TextStyle(fontSize: 12, color: theme.weakTextColor), + if (isDesktopScreen) + Container( + padding: const EdgeInsets.symmetric(vertical: 8), + child: TIMUIKitOperationItem( + isEmpty: false, + operationName: TIM_t("全员禁言"), + type: "switch", + isUseCheckedBoxOnWide: true, + operationDescription: TIM_t("全员禁言开启后,只允许群主和管理员发言。"), + operationValue: isAllMuted, + onSwitchChange: (value) { + widget.model.setMuteAll(value); + }, + ), ), - ), - if (!isAllMuted) + if (!isDesktopScreen) + Container( + padding: const EdgeInsets.symmetric( + vertical: 10, horizontal: 16), + color: theme.weakBackgroundColor, + alignment: Alignment.topLeft, + child: Text( + TIM_t("全员禁言开启后,只允许群主和管理员发言。"), + style: + TextStyle(fontSize: 12, color: theme.weakTextColor), + ), + ), + if (!isAllMuted && isAllowMuteMember) InkWell( child: Container( color: Colors.white, padding: const EdgeInsets.only(left: 16), child: Container( - padding: const EdgeInsets.symmetric( - vertical: 12, - ), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), + padding: !isDesktopScreen + ? const EdgeInsets.symmetric( + vertical: 12, + ) + : const EdgeInsets.only( + bottom: 4, + ), + decoration: isDesktopScreen + ? null + : BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), child: Row( children: [ Icon( @@ -232,58 +299,149 @@ class _GroupProfileGroupManagePageState ), )), onTap: () async { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GroupProfileAddAdmin( - appbarTitle: TIM_t("设置禁言"), - memberList: memberList.where((element) { - final isMute = (serverTime != null - ? (element?.muteUntil ?? 0) > - serverTime! - : false); - final isMember = element!.role == - GroupMemberRoleType - .V2TIM_GROUP_MEMBER_ROLE_MEMBER; - return !isMute && isMember; - }).toList(), - selectCompletedHandler: - (context, selectedMember) async { - if (selectedMember.isNotEmpty) { - for (var member in selectedMember) { - final userID = member!.userID; - widget.model - .muteGroupMember(userID, true, serverTime); - } - } - }, - ))); + Widget muteMember() { + return GroupProfileAddAdmin( + key: groupProfileAddAdminKey, + appbarTitle: TIM_t("设置禁言"), + memberList: memberList.where((element) { + final isMute = (serverTime != null + ? (element?.muteUntil ?? 0) > serverTime! + : false); + final isMember = element!.role == + GroupMemberRoleType + .V2TIM_GROUP_MEMBER_ROLE_MEMBER; + return !isMute && isMember; + }).toList(), + selectCompletedHandler: + (context, selectedMember) async { + if (selectedMember.isNotEmpty) { + for (var member in selectedMember) { + final userID = member!.userID; + widget.model + .muteGroupMember(userID, true, serverTime); + } + } + }, + ); + } + + if (isDesktopScreen) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.setMute, + context: context, + title: TIM_t("设置禁言"), + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.8, + onSubmit: () { + groupProfileAddAdminKey.currentState?.onSubmit(); + }, + child: (onClose) => muteMember()); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => muteMember())); + } }, ), - if (!isAllMuted) + if (!isAllMuted && isAllowMuteMember) ...memberList .where((element) => (serverTime != null ? (element?.muteUntil ?? 0) > serverTime! : false)) - .map((e) => _buildListItem( - context, - e!, - ActionPane(motion: const DrawerMotion(), children: [ - SlidableAction( - onPressed: (_) { - widget.model.muteGroupMember(e.userID, false, serverTime); + .map((e) => Container( + padding: isDesktopScreen + ? const EdgeInsets.only(left: 16) + : null, + child: GestureDetector( + onSecondaryTapDown: (details) { + TUIKitWidePopup.showPopupWindow( + operationKey: + TUIKitWideModalOperationKey.setUnmute, + isDarkBackground: false, + borderRadius: const BorderRadius.all( + Radius.circular(4)), + context: context, + offset: Offset( + min( + details.globalPosition.dx, + MediaQuery.of(context).size.width - + 80), + details.globalPosition.dy), + child: (onClose) => TUIKitColumnMenu(data: [ + ColumnMenuItem( + label: TIM_t("删除"), + icon: const Icon( + Icons.remove_circle_outline, + size: 16), + onClick: () { + widget.model.muteGroupMember( + e?.userID ?? "", + false, + serverTime); + onClose(); + }), + ])); }, - flex: 1, - backgroundColor: theme.cautionColor ?? - CommonColor.cautionColor, - autoClose: true, - label: TIM_t("删除"), - ) - ]))) + child: _buildListItem( + context, + e!, + ActionPane( + motion: const DrawerMotion(), + children: [ + SlidableAction( + onPressed: (_) { + widget.model.muteGroupMember( + e.userID, false, serverTime); + }, + flex: 1, + backgroundColor: theme.cautionColor ?? + CommonColor.cautionColor, + autoClose: true, + label: TIM_t("删除"), + ) + ])), + ), + )) .toList() ], - ), - ); + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: managePage(), + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("群管理"), + style: + TextStyle(color: theme.appbarTextColor, fontSize: 17), + ), + backgroundColor: theme.appbarBgColor ?? theme.primaryColor, + shadowColor: theme.weakDividerColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + ), + leading: IconButton( + padding: const EdgeInsets.only(left: 16), + constraints: const BoxConstraints(), + icon: Image.asset( + 'images/arrow_back.png', + package: 'tencent_cloud_chat_uikit', + height: 34, + width: 34, + color: theme.appbarTextColor, + ), + onPressed: () async { + if (isAllMuted != widget.model.groupInfo?.isAllMuted) { + widget.model.setMuteAll(isAllMuted); + } + Navigator.pop(context); + }, + ), + ), + body: managePage(), + )); }); } } @@ -305,43 +463,47 @@ _getShowName(V2TimGroupMemberFullInfo? item) { Widget _buildListItem(BuildContext context, V2TimGroupMemberFullInfo memberInfo, ActionPane? endActionPane) { final theme = Provider.of(context).theme; - return Container( + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + Widget nameItem() { + return Container( color: Colors.white, - child: ListView.builder( - itemCount: 1, - shrinkWrap: true, - itemBuilder: (context, index){ - return Slidable( - endActionPane: endActionPane, - child: Column(children: [ - ListTile( - tileColor: Colors.black, - leading: SizedBox( - width: 36, - height: 36, - child: Avatar( - faceUrl: memberInfo.faceUrl ?? "", - showName: _getShowName(memberInfo), - type: 2, - ), - ), - title: Row( - children: [ - Text(_getShowName(memberInfo), - style: const TextStyle(fontSize: 16)), - ], - ), - onTap: () {}, - ), - Divider( - thickness: 1, - indent: 74, - endIndent: 0, - color: theme.weakDividerColor, - height: 0) - ])); - }) - ); + child: Column(children: [ + ListTile( + tileColor: Colors.black, + leading: SizedBox( + width: isDesktopScreen ? 30 : 36, + height: isDesktopScreen ? 30 : 36, + child: Avatar( + faceUrl: memberInfo.faceUrl ?? "", + showName: _getShowName(memberInfo), + type: 2, + ), + ), + title: Row( + children: [ + Text(_getShowName(memberInfo), + style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)), + ], + ), + onTap: () {}, + ), + if (!isDesktopScreen) + Divider( + thickness: 1, + indent: 74, + endIndent: 0, + color: theme.weakDividerColor, + height: 0) + ]), + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: nameItem(), + defaultWidget: SingleChildScrollView( + child: Slidable(endActionPane: endActionPane, child: nameItem()))); } /// 选择管理员 @@ -350,6 +512,7 @@ class GroupProfileSetManagerPage extends StatefulWidget { const GroupProfileSetManagerPage({Key? key, required this.model}) : super(key: key); + @override State createState() => _GroupProfileSetManagerPageState(); } @@ -395,54 +558,65 @@ class _GroupProfileSetManagerPageState final adminList = _getAdminMemberList(memberList); final ownerList = _getOwnerList(memberList); final String option2 = adminList.length.toString(); - return Scaffold( - appBar: AppBar( - title: Text( - TIM_t("设置管理员"), - style: const TextStyle(color: Colors.white, fontSize: 17), - ), - shadowColor: theme.weakDividerColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, - ), - ), - body: SingleChildScrollView( + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + Widget adminPage() { + return SingleChildScrollView( child: Column( children: [ - Container( - alignment: Alignment.topLeft, - color: theme.weakDividerColor, - padding: - const EdgeInsets.symmetric(vertical: 6, horizontal: 16), - child: Text( - TIM_t("群主"), - style: TextStyle(fontSize: 14, color: theme.weakTextColor), + if (!isDesktopScreen) + Container( + alignment: Alignment.topLeft, + color: theme.weakDividerColor, + padding: + const EdgeInsets.symmetric(vertical: 6, horizontal: 16), + child: Text( + TIM_t("群主"), + style: TextStyle(fontSize: 14, color: theme.weakTextColor), + ), + ), + if (isDesktopScreen) + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(top: 10, bottom: 4, left: 16), + child: Text( + TIM_t("群主"), + style: TextStyle(fontSize: 14, color: theme.primaryColor), + ), ), - ), ...ownerList .map( - (e) => _buildListItem(context, e!, null), + (e) => Container( + padding: isDesktopScreen + ? const EdgeInsets.only(left: 16) + : null, + child: _buildListItem(context, e!, null), + ), ) .toList(), - Container( - alignment: Alignment.topLeft, - color: theme.weakDividerColor, - padding: - const EdgeInsets.symmetric(vertical: 6, horizontal: 16), - child: Text( - TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")( - option2: option2), - style: TextStyle(fontSize: 14, color: theme.weakTextColor), + if (!isDesktopScreen) + Container( + alignment: Alignment.topLeft, + color: theme.weakDividerColor, + padding: + const EdgeInsets.symmetric(vertical: 6, horizontal: 16), + child: Text( + TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")( + option2: option2), + style: TextStyle(fontSize: 14, color: theme.weakTextColor), + ), + ), + if (isDesktopScreen) + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(top: 10, bottom: 4, left: 16), + child: Text( + TIM_t_para("管理员 ({{option2}}/10)", "管理员 ($option2/10)")( + option2: option2), + style: TextStyle(fontSize: 14, color: theme.primaryColor), + ), ), - ), InkWell( child: Container( color: Colors.white, @@ -451,12 +625,14 @@ class _GroupProfileSetManagerPageState padding: const EdgeInsets.symmetric( vertical: 12, ), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), + decoration: isDesktopScreen + ? null + : BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), child: Row( children: [ Icon( @@ -472,49 +648,131 @@ class _GroupProfileSetManagerPageState ), )), onTap: () async { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GroupProfileAddAdmin( - memberList: memberList - .where((element) => - element?.role == - GroupMemberRoleType - .V2TIM_GROUP_MEMBER_ROLE_MEMBER) - .toList(), - appbarTitle: TIM_t("设置管理员"), - selectCompletedHandler: - (context, selectedMember) async { - if (selectedMember.isNotEmpty) { - for (var member in selectedMember) { - final userID = member!.userID; - widget.model.setMemberToAdmin(userID); - } + if (isDesktopScreen) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.setAdmins, + context: context, + title: TIM_t("设置管理员"), + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.8, + onSubmit: () { + groupProfileAddAdminKey.currentState?.onSubmit(); + }, + child: (onClose) => GroupProfileAddAdmin( + key: groupProfileAddAdminKey, + memberList: memberList + .where((element) => + element?.role == + GroupMemberRoleType + .V2TIM_GROUP_MEMBER_ROLE_MEMBER) + .toList(), + appbarTitle: TIM_t("设置管理员"), + selectCompletedHandler: + (context, selectedMember) async { + if (selectedMember.isNotEmpty) { + for (var member in selectedMember) { + final userID = member!.userID; + widget.model.setMemberToAdmin(userID); } - }, - ))); + } + }, + )); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => GroupProfileAddAdmin( + key: groupProfileAddAdminKey, + memberList: memberList + .where((element) => + element?.role == + GroupMemberRoleType + .V2TIM_GROUP_MEMBER_ROLE_MEMBER) + .toList(), + appbarTitle: TIM_t("设置管理员"), + selectCompletedHandler: + (context, selectedMember) async { + if (selectedMember.isNotEmpty) { + for (var member in selectedMember) { + final userID = member!.userID; + widget.model.setMemberToAdmin(userID); + } + } + }, + ))); + } }, ), ...adminList - .map((e) => _buildListItem( - context, - e!, - ActionPane(motion: const DrawerMotion(), children: [ - SlidableAction( - onPressed: (_) { - _removeAdmin(context, e); - }, - flex: 1, - backgroundColor: - theme.cautionColor ?? CommonColor.cautionColor, - autoClose: true, - label: TIM_t("删除"), - ) - ]))) + .map((e) => GestureDetector( + onSecondaryTapDown: (details) { + TUIKitWidePopup.showPopupWindow( + operationKey: + TUIKitWideModalOperationKey.deleteAdmin, + isDarkBackground: false, + borderRadius: + const BorderRadius.all(Radius.circular(4)), + context: context, + offset: Offset( + min(details.globalPosition.dx, + MediaQuery.of(context).size.width - 80), + details.globalPosition.dy), + child: (onClose) => TUIKitColumnMenu(data: [ + ColumnMenuItem( + label: TIM_t("删除"), + icon: const Icon( + Icons.remove_circle_outline, + size: 16), + onClick: () { + _removeAdmin(context, e!); + onClose(); + }), + ])); + }, + child: Container( + padding: isDesktopScreen + ? const EdgeInsets.only(left: 16) + : null, + child: _buildListItem( + context, + e!, + ActionPane( + motion: const DrawerMotion(), + children: [ + SlidableAction( + onPressed: (_) { + _removeAdmin(context, e); + }, + flex: 1, + backgroundColor: theme.cautionColor ?? + CommonColor.cautionColor, + autoClose: true, + label: TIM_t("删除"), + ) + ])), + ), + )) .toList(), ], - )), - ); + )); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: adminPage(), + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("设置管理员"), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), + ), + shadowColor: theme.weakDividerColor, + backgroundColor: theme.appbarBgColor ?? theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + ), + ), + body: adminPage(), + )); }, ); } @@ -542,59 +800,18 @@ class GroupProfileAddAdmin extends StatefulWidget { class _GroupProfileAddAdminState extends TIMUIKitState { List selectedMemberList = []; + void onSubmit() { + if (widget.selectCompletedHandler != null) { + widget.selectCompletedHandler!(context, selectedMemberList); + } + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - return Scaffold( - appBar: AppBar( - title: Text( - widget.appbarTitle, - style: const TextStyle(color: Colors.white, fontSize: 17), - ), - shadowColor: theme.weakDividerColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, - ), - leading: TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: Text( - TIM_t("取消"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - actions: [ - TextButton( - onPressed: () { - if (widget.selectCompletedHandler != null) { - widget.selectCompletedHandler!(context, selectedMemberList); - } - Navigator.of(context).pop(); - }, - child: Text( - TIM_t("完成"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ) - ], - ), - body: SingleChildScrollView( + Widget addAdminPage() { + return SingleChildScrollView( child: Column( children: [ Container( @@ -655,7 +872,54 @@ class _GroupProfileAddAdminState extends TIMUIKitState { )) .toList(), ], - )), - ); + )); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: addAdminPage(), + ), + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + widget.appbarTitle, + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), + ), + shadowColor: theme.weakDividerColor, + backgroundColor: theme.appbarBgColor ?? theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + ), + leadingWidth: 80, + leading: TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text( + TIM_t("取消"), + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 14, + ), + ), + ), + actions: [ + TextButton( + onPressed: () { + onSubmit(); + Navigator.of(context).pop(); + }, + child: Text( + TIM_t("完成"), + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 14, + ), + ), + ) + ], + ), + body: addAdminPage())); } } diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_member_tile.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_member_tile.dart index 1b6661f..6f84e95 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_member_tile.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_member_tile.dart @@ -5,7 +5,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; - +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_member/tui_add_group_member.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_member/tui_delete_group_member.dart'; @@ -13,6 +14,7 @@ import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/group_mem import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/wide_popup.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; class GroupMemberTile extends TIMUIKitStatelessWidget { @@ -20,9 +22,9 @@ class GroupMemberTile extends TIMUIKitStatelessWidget { Key? key, }) : super(key: key); - List _getMemberList(memberList) { - if (memberList.length > 8) { - return memberList.getRange(0, 8).toList(); + List _getMemberList(memberList, int showRange) { + if (memberList.length > showRange) { + return memberList.getRange(0, showRange).toList(); } else { return memberList; } @@ -36,43 +38,47 @@ class GroupMemberTile extends TIMUIKitStatelessWidget { return friendRemark != "" ? friendRemark : showName; } - List _groupMemberListBuilder( - List memberList, TUITheme theme, TUIGroupProfileModel model) { - return _getMemberList(memberList).map((element) { + List _groupMemberListBuilder(List memberList, TUITheme theme, + TUIGroupProfileModel model, int showRange) { + final isDesktopScreen = TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop; + return _getMemberList(memberList, showRange).map((element) { final faceUrl = element?.faceUrl ?? ""; final showName = _getShowName(element); - return GestureDetector( - onTap: () { + return InkWell( + onTapDown: (details) { if (model.onClickUser != null && element?.userID != null) { - model.onClickUser!(element!.userID); + model.onClickUser!(element!.userID, details); } }, child: SizedBox( - width: 60, - height: 76, + width: isDesktopScreen ? 36 : 60, + height: isDesktopScreen ? 36 : 76, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( - width: 50, - height: 50, + width: isDesktopScreen ? 36 : 50, + height: isDesktopScreen ? 36 : 50, child: Avatar( + borderRadius: isDesktopScreen ? BorderRadius.circular(18) : null, faceUrl: faceUrl, showName: showName, type: 1, ), ), - const SizedBox( - height: 8, - ), - Text( - showName, - textAlign: TextAlign.center, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: theme.weakTextColor, - fontSize: 10), - ) + if (!isDesktopScreen) + const SizedBox( + height: 8, + ), + if (!isDesktopScreen) + Text( + showName, + textAlign: TextAlign.center, + style: TextStyle( + overflow: TextOverflow.ellipsis, + color: theme.weakTextColor, + fontSize: 10), + ) ], ), ), @@ -85,51 +91,85 @@ class GroupMemberTile extends TIMUIKitStatelessWidget { return []; } + void navigateToMemberList(BuildContext context, TUIGroupProfileModel model, + List memberList) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + if (!isDesktopScreen) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => GroupProfileMemberListPage( + model: model, memberList: memberList), + )); + } else { + final option1 = memberList.length.toString(); + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.groupMembersList, + context: context, + width: MediaQuery.of(context).size.width * 0.5, + height: MediaQuery.of(context).size.height * 0.8, + title: TIM_t_para("群成员({{option1}}人)", "群成员($option1人)")( + option1: option1), + child: (onClose) => + GroupProfileMemberListPage(model: model, memberList: memberList)); + } + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final model = Provider.of(context); final memberAmount = model.groupInfo?.memberCount ?? 0; final option1 = memberAmount.toString(); final memberList = model.groupMemberList; final isCanInviteMember = model.canInviteMember(); final isCanKickOffMember = model.canKickOffMember(); + + int showRange = isDesktopScreen ? 7 : 8; + if (isDesktopScreen && isCanInviteMember) { + showRange--; + } + if (isDesktopScreen && isCanKickOffMember) { + showRange--; + } + return Container( - padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), color: Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.only(bottom: 12), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), + decoration: isDesktopScreen + ? null + : BoxDecoration( + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), child: InkWell( onTap: () async { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GroupProfileMemberListPage( - model: model, memberList: memberList), - )); + navigateToMemberList(context, model, memberList); }, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(TIM_t("群成员"), - style: - TextStyle(color: theme.darkTextColor, fontSize: 16)), + style: TextStyle( + color: theme.darkTextColor, + fontSize: isDesktopScreen ? 14 : 16)), Row( children: [ Text( TIM_t_para("{{option1}}人", "$option1人")( option1: option1), - style: - TextStyle(color: theme.darkTextColor, fontSize: 16), + style: TextStyle( + color: theme.darkTextColor, + fontSize: isDesktopScreen ? 14 : 16), ), Icon( Icons.keyboard_arrow_right, @@ -141,83 +181,151 @@ class GroupMemberTile extends TIMUIKitStatelessWidget { ), ), ), + if (isDesktopScreen) + InkWell( + onTap: () async { + navigateToMemberList(context, model, memberList); + }, + child: Container( + decoration: BoxDecoration( + border: Border.all( + width: 1, + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor), + borderRadius: const BorderRadius.all(Radius.circular(4)), + ), + // height: 30, + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 6), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon( + Icons.search, + color: hexToColor("979797"), + size: 16, + ), + const SizedBox(width: 6), + Text(TIM_t("搜索"), + style: TextStyle( + color: theme.weakTextColor, + fontSize: 12, + )), + ], + ), + ), + ), Container( // height: 90, padding: const EdgeInsets.only(top: 12), child: Wrap( - spacing: 20, + spacing: isDesktopScreen ? 10 : 20, runSpacing: 10, alignment: WrapAlignment.start, children: [ - ..._groupMemberListBuilder(memberList, theme, model), + ..._groupMemberListBuilder(memberList, theme, model, showRange), if (isCanInviteMember) DottedBorder( borderType: BorderType.RRect, - radius: const Radius.circular(4.5), + radius: Radius.circular(isDesktopScreen ? 18 : 4.5), color: theme.weakTextColor!, dashPattern: const [6, 3], child: SizedBox( - width: 48, - height: 48, + width: isDesktopScreen ? 32 : 48, + height: isDesktopScreen ? 32 : 48, child: IconButton( onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - AddGroupMemberPage(model: model), - )); + if (isDesktopScreen) { + TUIKitWidePopup.showPopupWindow( + context: context, + operationKey: TUIKitWideModalOperationKey.addGroupMembers, + width: 350, + title: TIM_t("添加群成员"), + height: 460, + onSubmit: () { + addGroupMemberKey.currentState?.submitAdd(); + }, + child: (onClose) => AddGroupMemberPage( + model: model, + key: addGroupMemberKey, + )); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AddGroupMemberPage( + model: model, + ), + )); + } }, - icon: const Icon(Icons.add), + icon: Icon( + Icons.add, + size: isDesktopScreen ? 16 : 18, + ), color: theme.weakTextColor, ), )), - // if (isCanInviteMember) - // const SizedBox( - // width: 21, - // ), if (isCanKickOffMember) DottedBorder( borderType: BorderType.RRect, - radius: const Radius.circular(4.5), + radius: Radius.circular(isDesktopScreen ? 18 : 4.5), color: theme.weakTextColor!, dashPattern: const [6, 3], child: SizedBox( - width: 48, - height: 48, + width: isDesktopScreen ? 32 : 48, + height: isDesktopScreen ? 32 : 48, child: IconButton( onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - DeleteGroupMemberPage(model: model), - )); + if (isDesktopScreen) { + TUIKitWidePopup.showPopupWindow( + operationKey: TUIKitWideModalOperationKey.kickOffGroupMembers, + context: context, + width: 350, + title: TIM_t("删除群成员"), + height: 460, + onSubmit: () { + deleteGroupMemberKey.currentState + ?.submitDelete(); + }, + child: (onClose) => DeleteGroupMemberPage( + model: model, + key: deleteGroupMemberKey, + ), + ); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + DeleteGroupMemberPage(model: model), + )); + } }, - icon: const Icon(Icons.remove), + icon: Icon( + Icons.remove, + size: isDesktopScreen ? 16 : 18, + ), color: theme.weakTextColor, ), )), ], ), ), - if (memberList.length > 8) - GestureDetector( + if (memberList.length > showRange) + InkWell( child: Container( alignment: Alignment.center, - margin: const EdgeInsets.only(top: 16), + margin: EdgeInsets.only(top: isDesktopScreen ? 12 : 16), child: Text( TIM_t("查看更多群成员"), - style: TextStyle(color: theme.weakTextColor, fontSize: 14), + style: TextStyle( + color: theme.weakTextColor, + fontSize: isDesktopScreen ? 12 : 14), ), ), onTap: () async { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GroupProfileMemberListPage( - model: model, memberList: memberList), - )); + navigateToMemberList(context, model, memberList); }, ), ], diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_message_disturb.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_message_disturb.dart index 41361f1..91cf421 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_message_disturb.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_message_disturb.dart @@ -15,8 +15,10 @@ class GroupMessageDisturb extends TIMUIKitStatelessWidget { final model = Provider.of(context); final isDisturb = model.conversation?.recvOpt != 0; return TIMUIKitOperationItem( + isEmpty: false, operationName: TIM_t("消息免打扰"), type: "switch", + isUseCheckedBoxOnWide: true, operationValue: isDisturb, onSwitchChange: (value) { model.setMessageDisturb(value); diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_name_card.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_name_card.dart index de39696..cf6c39d 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_name_card.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_name_card.dart @@ -2,63 +2,141 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/text_input_bottom_sheet.dart'; - import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; -class GroupProfileNameCard extends TIMUIKitStatelessWidget { - GroupProfileNameCard({Key? key}) : super(key: key); +class GroupProfileNameCard extends StatefulWidget { + const GroupProfileNameCard({Key? key}) : super(key: key); + + @override + State createState() => GroupProfileNameCardState(); + +} + +class GroupProfileNameCardState extends TIMUIKitState{ final TextEditingController controller = TextEditingController(); + String? nameCard; @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final model = Provider.of(context); if (model == null) { return Container(); } - final nameCard = model.getSelfNameCard(); + nameCard = model.getSelfNameCard(); + controller.text = nameCard ?? ""; - controller.text = nameCard; return Container( - padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: Colors.white, - border: Border( + border: isDesktopScreen ? null : Border( bottom: BorderSide( color: - theme.weakDividerColor ?? CommonColor.weakDividerColor))), - child: InkWell( + theme.weakDividerColor ?? CommonColor.weakDividerColor))), + child: GestureDetector( onTap: () async { - TextInputBottomSheet.showTextInputBottomSheet( - context, TIM_t("修改我的群昵称"), TIM_t("仅限中文、字母、数字和下划线,2-20个字"), - (String nameCard) async { - final text = nameCard.trim(); - model.setNameCard(text); - }, theme); + if (!isDesktopScreen) { + TextInputBottomSheet.showTextInputBottomSheet( + context: context, + title: TIM_t("修改我的群昵称"), + tips: TIM_t("仅限中文、字母、数字和下划线,2-20个字"), + onSubmitted: (String nameCard) async { + final text = nameCard.trim(); + model.setNameCard(text); + }, + theme: theme); + } }, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - TIM_t("我的群昵称"), - style: TextStyle(fontSize: 16, color: theme.darkTextColor), - ), Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - nameCard, - style: const TextStyle(fontSize: 16, color: Colors.black), + Container( + margin: const EdgeInsets.only(right: 10), + child: Text( + TIM_t("我的群昵称"), + style: TextStyle( + fontSize: isDesktopScreen ? 14 : 16, + color: theme.darkTextColor), + ), ), - Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor) + if (!isDesktopScreen) + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + child: Text( + nameCard ?? "", + style: TextStyle( + fontSize: isDesktopScreen ? 14 : 16, + color: theme.darkTextColor), + )), + Icon(Icons.keyboard_arrow_right, + color: theme.weakTextColor) + ], + )), ], - ) + ), + if (isDesktopScreen) + Text( + TIM_t("仅限中文、字母、数字和下划线,2-20个字"), + style: TextStyle(color: theme.weakTextColor, fontSize: 12), + ), + if (isDesktopScreen) + Container( + margin: const EdgeInsets.symmetric(vertical: 10), + height: 30, + child: TextField( + minLines: 1, + controller: controller, + maxLines: 1, + onSubmitted: (text) { + model.setNameCard(text.trim()); + }, + keyboardType: TextInputType.multiline, + autofocus: true, + textAlignVertical: TextAlignVertical.center, + textAlign: TextAlign.start, + style: const TextStyle(fontSize: 12), + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 10), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5.0), + borderSide: BorderSide( + color: theme.weakDividerColor ?? Colors.grey, + )), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5.0), + borderSide: BorderSide( + color: theme.weakDividerColor ?? Colors.grey, + ), + ), + focusedBorder: OutlineInputBorder( + //选中时外边框颜色 + borderRadius: BorderRadius.circular(5.0), + borderSide: BorderSide( + color: theme.weakTextColor ?? Colors.grey, + ), + ), + hintStyle: const TextStyle( + color: Color(0xFFAEA4A3), + ), + hintText: TIM_t("修改我的群昵称"))), + ), ], ), ), diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_notification.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_notification.dart index a45c2e8..19cda17 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_notification.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_notification.dart @@ -1,63 +1,161 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; -import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; - - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; -class GroupProfileNotification extends TIMUIKitStatelessWidget { - GroupProfileNotification({Key? key}) : super(key: key); +class GroupProfileNotification extends StatefulWidget { + final bool isHavePermission; + + const GroupProfileNotification({Key? key, this.isHavePermission = false}) + : super(key: key); + + @override + State createState() => GroupProfileNotificationState(); +} + +class GroupProfileNotificationState + extends TIMUIKitState { + bool isShowEditBox = false; + final TextEditingController _controller = TextEditingController(); + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final model = Provider.of(context); final String notification = (model.groupInfo?.notification != null && model.groupInfo!.notification!.isNotEmpty) ? model.groupInfo!.notification! : TIM_t("暂无群公告"); + + _setGroupNotification() async { + setState(() { + isShowEditBox = false; + }); + final notification = _controller.text; + await model.setGroupNotification(notification); + } + return Container( - padding: const EdgeInsets.only(top: 12, left: 16, bottom: 12), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( color: Colors.white, - border: Border( - bottom: BorderSide( - color: - theme.weakDividerColor ?? CommonColor.weakDividerColor))), + border: isDesktopScreen + ? null + : Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), child: InkWell( - onTap: (() { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GroupProfileNotificationPage( - model: model, notification: notification))); - }), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, + onTap: !widget.isHavePermission + ? null + : (() { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + if (!isDesktopScreen) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => GroupProfileNotificationPage( + model: model, notification: notification))); + } else { + setState(() { + isShowEditBox = !isShowEditBox; + if (isShowEditBox) { + _controller.text = notification; + } + }); + } + }), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Text( TIM_t("群公告"), - style: TextStyle(color: theme.darkTextColor, fontSize: 16), + style: TextStyle( + color: theme.darkTextColor, + fontSize: isDesktopScreen ? 14 : 16), ), - Text(notification, - overflow: TextOverflow.ellipsis, - softWrap: true, - style: - TextStyle(color: theme.weakTextColor, fontSize: 12)), - ], - ), + ), + if (widget.isHavePermission) + AnimatedRotation( + turns: isShowEditBox ? 0.25 : 0, + duration: const Duration(milliseconds: 200), + child: Icon(Icons.keyboard_arrow_right, + color: theme.weakTextColor), + ) + ], ), - Icon(Icons.keyboard_arrow_right, color: theme.weakTextColor) + if (!isShowEditBox) + Padding( + padding: EdgeInsets.only(top: isDesktopScreen ? 4 : 0), + child: SelectableText(notification, + // overflow: isDesktopScreen ? null : TextOverflow.ellipsis, + // softWrap: true, + style: TextStyle(color: theme.weakTextColor, fontSize: 12)), + ), + if (isShowEditBox) + Container( + margin: const EdgeInsets.only(top: 10, bottom: 10), + // height: 150, + child: TextField( + minLines: 1, + maxLines: 6, + controller: _controller, + keyboardType: TextInputType.multiline, + autofocus: true, + style: const TextStyle(fontSize: 13), + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric( + horizontal: 10, vertical: 10), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(5.0), + borderSide: BorderSide( + color: theme.weakDividerColor ?? Colors.grey, + )), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(5.0), + borderSide: BorderSide( + color: theme.weakDividerColor ?? Colors.grey, + ), + ), + focusedBorder: OutlineInputBorder( + //选中时外边框颜色 + borderRadius: BorderRadius.circular(5.0), + borderSide: BorderSide( + color: theme.weakTextColor ?? Colors.grey, + ), + ), + hintStyle: const TextStyle( + color: Color(0xFFAEA4A3), + ), + hintText: '')), + ), + if (isShowEditBox) + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + OutlinedButton( + onPressed: _setGroupNotification, + child: Text( + TIM_t("保存"), + style: + TextStyle(fontSize: 13, color: theme.primaryColor), + )) + ], + ) ], ), ), @@ -104,19 +202,13 @@ class _GroupProfileNotificationPageState appBar: AppBar( title: Text( TIM_t("群公告"), - style: const TextStyle(color: Colors.white, fontSize: 17), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), ), + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, shadowColor: theme.weakDividerColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, + iconTheme: IconThemeData( + color: theme.appbarTextColor, ), actions: [ TextButton( @@ -131,9 +223,9 @@ class _GroupProfileNotificationPageState }, child: Text( isUpdated ? TIM_t("编辑") : TIM_t("完成"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 14, ), ), ) diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_pin_conversation.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_pin_conversation.dart index e3605d9..eaf29a2 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_pin_conversation.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_pin_conversation.dart @@ -15,8 +15,10 @@ class GroupPinConversation extends TIMUIKitStatelessWidget { final model = Provider.of(context); final isPined = model.conversation?.isPinned ?? false; return TIMUIKitOperationItem( + isEmpty: false, operationName: TIM_t("置顶聊天"), type: "switch", + isUseCheckedBoxOnWide: true, operationValue: isPined, onSwitchChange: (value) { model.pinedConversation(value); diff --git a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_type.dart b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_type.dart index 0b24447..1f1284d 100644 --- a/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_type.dart +++ b/lib/ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_type.dart @@ -3,9 +3,8 @@ import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_group_profile_model.dart'; - - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; class GroupProfileType extends TIMUIKitStatelessWidget { @@ -17,6 +16,9 @@ class GroupProfileType extends TIMUIKitStatelessWidget { String groupType; final model = Provider.of(context); + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final type = model.groupInfo?.groupType; switch (type) { case GroupType.AVChatRoom: @@ -40,7 +42,7 @@ class GroupProfileType extends TIMUIKitStatelessWidget { padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), decoration: BoxDecoration( color: Colors.white, - border: Border( + border: isDesktopScreen ? null : Border( bottom: BorderSide( color: theme.weakDividerColor ?? CommonColor.weakDividerColor))), @@ -49,11 +51,13 @@ class GroupProfileType extends TIMUIKitStatelessWidget { children: [ Text( TIM_t("群类型"), - style: TextStyle(fontSize: 16, color: theme.darkTextColor), + style: TextStyle( + fontSize: isDesktopScreen ? 14 : 16, color: theme.darkTextColor), ), Text( groupType, - style: const TextStyle(fontSize: 16, color: Colors.black), + style: TextStyle( + fontSize: isDesktopScreen ? 14 : 16, color: theme.weakTextColor), ) ], ), diff --git a/lib/ui/views/TIMUIKitNewContact/tim_uikit_new_contact.dart b/lib/ui/views/TIMUIKitNewContact/tim_uikit_new_contact.dart index cfc071c..b59f2c0 100644 --- a/lib/ui/views/TIMUIKitNewContact/tim_uikit_new_contact.dart +++ b/lib/ui/views/TIMUIKitNewContact/tim_uikit_new_contact.dart @@ -4,7 +4,8 @@ import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/life_cycle/new_contact_life_cycle.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; -import 'package:tencent_im_base/tencent_im_base.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; @@ -44,9 +45,8 @@ class _TIMUIKitNewContactState extends TIMUIKitState { late TUIFriendShipViewModel model = serviceLocator(); _getShowName(V2TimFriendApplication item) { - final nickName = item.nickname ?? ""; - final userID = item.userID; - return nickName != "" ? nickName : userID; + return TencentUtils.checkString(item.nickname) ?? + TencentUtils.checkString(item.userID); } Widget _itemBuilder( @@ -54,104 +54,143 @@ class _TIMUIKitNewContactState extends TIMUIKitState { final theme = Provider.of(context).theme; final showName = _getShowName(applicationInfo); final faceUrl = applicationInfo.faceUrl ?? ""; - return Container( - padding: const EdgeInsets.only(top: 10, left: 16), - child: Row( - children: [ - Container( - padding: const EdgeInsets.only(bottom: 12), - margin: const EdgeInsets.only(right: 12), - child: SizedBox( - height: 40, - width: 40, - child: Avatar(faceUrl: faceUrl, showName: showName), - ), - ), - Expanded( - child: Container( - padding: const EdgeInsets.only(top: 10, bottom: 20), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - showName, - style: const TextStyle(color: Colors.black, fontSize: 18), + final applicationText = applicationInfo.addWording ?? ""; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + return Material( + color: theme.wideBackgroundColor, + child: InkWell( + onTap: () {}, + child: Container( + padding: EdgeInsets.only( + top: isDesktopScreen ? 6 : 10, + left: 16, + right: isDesktopScreen ? 16 : 0), + child: Row( + children: [ + Container( + padding: EdgeInsets.only(bottom: isDesktopScreen ? 10 : 12), + margin: const EdgeInsets.only(right: 12), + child: SizedBox( + height: isDesktopScreen ? 30 : 40, + width: isDesktopScreen ? 30 : 40, + child: Avatar(faceUrl: faceUrl, showName: showName), ), - Expanded(child: Container()), - Container( - margin: const EdgeInsets.only(right: 8), - child: InkWell( - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 14, vertical: 6), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - color: theme.primaryColor, - border: Border.all( - width: 1, - color: theme.weakTextColor ?? - CommonColor.weakTextColor)), - child: Text( - TIM_t("同意"), - style: const TextStyle( - color: Colors.white, - ), + ), + Expanded( + child: Container( + padding: const EdgeInsets.only(top: 10, bottom: 20), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.only( + top: (applicationText.isNotEmpty && isDesktopScreen) + ? 10 + : 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + showName, + style: TextStyle( + color: theme.darkTextColor, + fontSize: isDesktopScreen ? 14 : 18), + ), + if (applicationText.isNotEmpty && isDesktopScreen) + const SizedBox( + height: 4, + ), + if (applicationText.isNotEmpty && isDesktopScreen) + Text( + applicationText, + style: TextStyle( + color: theme.weakTextColor, fontSize: 12), + ), + ], ), ), - onTap: () async { - await model.acceptFriendApplication( - applicationInfo.userID, - applicationInfo.type, - ); - model.loadData(); - if (widget.onAccept != null) { - widget.onAccept!(applicationInfo); - } - // widget?.onAccept(); - }, - ), - ), - Container( - margin: const EdgeInsets.only(right: 8), - child: InkWell( - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8), - color: Colors.white, - border: Border.all( - width: 1, - color: theme.weakTextColor ?? - CommonColor.weakTextColor)), - padding: const EdgeInsets.symmetric( - horizontal: 14, vertical: 6), - child: Text( - TIM_t("拒绝"), - style: TextStyle( - color: theme.primaryColor, + Expanded(child: Container()), + Container( + margin: const EdgeInsets.only(right: 8), + child: InkWell( + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 14, vertical: 6), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: theme.primaryColor, + border: Border.all( + width: 1, + color: theme.weakTextColor ?? + CommonColor.weakTextColor)), + child: Text( + TIM_t("同意"), + style: TextStyle( + color: Colors.white, + fontSize: isDesktopScreen ? 12 : null, + ), ), ), + onTap: () async { + await model.acceptFriendApplication( + applicationInfo.userID, + applicationInfo.type, + ); + model.loadData(); + if (widget.onAccept != null) { + widget.onAccept!(applicationInfo); + } + // widget?.onAccept(); + }, ), - onTap: () async { - await model.refuseFriendApplication( - applicationInfo.userID, - applicationInfo.type, - ); - model.loadData(); - if (widget.onRefuse != null) { - widget.onRefuse!(applicationInfo); - } - // refuse(context); - }, - )) - ], - ), - )) - ], + ), + Container( + margin: const EdgeInsets.only(right: 8), + child: InkWell( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: Colors.white, + border: Border.all( + width: 1, + color: theme.weakTextColor ?? + CommonColor.weakTextColor)), + padding: const EdgeInsets.symmetric( + horizontal: 14, vertical: 6), + child: Text( + TIM_t("拒绝"), + style: TextStyle( + color: theme.primaryColor, + fontSize: isDesktopScreen ? 12 : null, + ), + ), + ), + onTap: () async { + await model.refuseFriendApplication( + applicationInfo.userID, + applicationInfo.type, + ); + model.loadData(); + if (widget.onRefuse != null) { + widget.onRefuse!(applicationInfo); + } + // refuse(context); + }, + )) + ], + ), + )) + ], + ), + ), ), ); } @@ -160,11 +199,6 @@ class _TIMUIKitNewContactState extends TIMUIKitState { return widget.itemBuilder ?? _itemBuilder; } - @override - void initState() { - super.initState(); - } - @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { return MultiProvider( diff --git a/lib/ui/views/TIMUIKitNewContact/tim_uikit_unread_count.dart b/lib/ui/views/TIMUIKitNewContact/tim_uikit_unread_count.dart index 177bbea..230fbd5 100644 --- a/lib/ui/views/TIMUIKitNewContact/tim_uikit_unread_count.dart +++ b/lib/ui/views/TIMUIKitNewContact/tim_uikit_unread_count.dart @@ -20,10 +20,6 @@ class TIMUIKitUnreadCount extends StatefulWidget { class _TIMUIKitUnreadCountState extends TIMUIKitState { final TUIFriendShipViewModel model = serviceLocator(); - @override - void initState() { - super.initState(); - } @override void dispose() { diff --git a/lib/ui/views/TIMUIKitProfile/tim_uikit_profile.dart b/lib/ui/views/TIMUIKitProfile/tim_uikit_profile.dart index e8d788e..37a65cf 100644 --- a/lib/ui/views/TIMUIKitProfile/tim_uikit_profile.dart +++ b/lib/ui/views/TIMUIKitProfile/tim_uikit_profile.dart @@ -8,6 +8,7 @@ import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_inf import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/profile_widget.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_widget.dart'; @@ -79,6 +80,9 @@ class TIMUIKitProfile extends StatefulWidget { /// Default: [false]. final bool isSelf; + /// Is use the small card mode on Desktop. Usually shows on the Chat page. + final bool smallCardMode; + const TIMUIKitProfile( {Key? key, required this.userID, @@ -97,7 +101,8 @@ class TIMUIKitProfile extends StatefulWidget { this.profileWidgetsOrder, this.builder, this.isSelf = false, - this.lifeCycle}) + this.lifeCycle, + this.smallCardMode = false}) : super(key: key); @override @@ -125,8 +130,10 @@ class _TIMUIKitProfileState extends TIMUIKitState { @override void didUpdateWidget(covariant TIMUIKitProfile oldWidget) { super.didUpdateWidget(oldWidget); - if(oldWidget.userID != widget.userID){ - _model.loadData(userID: widget.userID, isNeedConversation: !widget.isSelf); + if (oldWidget.userID != widget.userID) { + _model.userProfile = null; + _model.loadData( + userID: widget.userID, isNeedConversation: !widget.isSelf); } } @@ -145,6 +152,8 @@ class _TIMUIKitProfileState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return ChangeNotifierProvider.value( value: _model, child: Consumer( @@ -164,7 +173,16 @@ class _TIMUIKitProfileState extends TIMUIKitState { } final conversation = model.userProfile?.conversation ?? - V2TimConversation(conversationID: "c2c_${widget.userID}"); + V2TimConversation( + conversationID: "c2c_${widget.userID}", + type: 1, + userID: widget.userID, + faceUrl: model.userProfile?.friendInfo?.userProfile?.faceUrl, + showName: TencentUtils.checkString( + model.userProfile?.friendInfo?.friendRemark) ?? + TencentUtils.checkString(model + .userProfile?.friendInfo?.userProfile?.nickName) ?? + widget.userID); final TUISelfInfoViewModel _selfInfoViewModel = serviceLocator(); @@ -172,12 +190,16 @@ class _TIMUIKitProfileState extends TIMUIKitState { final isSelf = (model.userProfile?.friendInfo?.userID == _selfInfoViewModel.loginInfo?.userID); final isMute = model.isDisturb ?? false; + Widget profilePage({required Widget child}) { - return SingleChildScrollView( - physics: const BouncingScrollPhysics( - parent: AlwaysScrollableScrollPhysics()), - child: Container( - child: child, + return Container( + color: isDesktopScreen ? theme.wideBackgroundColor : null, + child: SingleChildScrollView( + physics: const BouncingScrollPhysics( + parent: AlwaysScrollableScrollPhysics()), + child: Container( + child: child, + ), ), ); } @@ -194,16 +216,21 @@ class _TIMUIKitProfileState extends TIMUIKitState { model.setMessageDisturb(userInfo.userID, value); } - void handleTapRemarkBar() { + void handleTapRemarkBar({Offset? offset, String? initText}) { _controller.showTextInputBottomSheet( - context, TIM_t("修改备注名"), TIM_t("仅限汉字、英文、数字和下划线"), - (String remark) async { - final res = - await _controller.updateRemarks(widget.userID, remark); - if (res.code == 0) { - widget.lifeCycle?.didRemarkUpdated(remark); - } - }, theme); + initOffset: offset, + initText: initText, + context: context, + title: TIM_t("修改备注名"), + tips: TIM_t("仅限汉字、英文、数字和下划线"), + onSubmitted: (String remark) async { + final res = + await _controller.updateRemarks(widget.userID, remark); + if (res.code == 0) { + widget.lifeCycle?.didRemarkUpdated(remark); + } + }, + theme: theme); } void handleAddFriend() async { @@ -275,7 +302,7 @@ class _TIMUIKitProfileState extends TIMUIKitState { model.isAddToBlackList ?? false, context, handleAddToBlockList, - ))!; + widget.smallCardMode))!; case ProfileWidgetEnum.pinConversationBar: // if (!isFriend) { // return Container(); @@ -286,15 +313,16 @@ class _TIMUIKitProfileState extends TIMUIKitState { : TIMUIKitProfileWidget.pinConversationBar( conversation.isPinned ?? false, context, - handlePinConversation))!; + handlePinConversation, + widget.smallCardMode))!; case ProfileWidgetEnum.messageMute: // if (!isFriend) { // return Container(); // } return (customBuilder?.messageMute != null ? customBuilder?.messageMute!(isMute, handleMuteMessage) - : TIMUIKitProfileWidget.messageDisturb( - context, isMute, handleMuteMessage))!; + : TIMUIKitProfileWidget.messageDisturb(context, isMute, + handleMuteMessage, widget.smallCardMode))!; case ProfileWidgetEnum.searchBar: return (customBuilder?.searchBar != null ? customBuilder?.searchBar!(conversation) @@ -305,37 +333,43 @@ class _TIMUIKitProfileState extends TIMUIKitState { ? customBuilder?.portraitBar!(userInfo.userProfile) : TIMUIKitProfileWidget.portraitBar( TIMUIKitProfileWidget.defaultPortraitWidget( - userInfo.userProfile)))!; + userInfo.userProfile, widget.smallCardMode), + widget.smallCardMode))!; case ProfileWidgetEnum.nicknameBar: return (customBuilder?.nicknameBar != null ? customBuilder ?.nicknameBar!(userInfo.userProfile?.nickName ?? "") : TIMUIKitProfileWidget.nicknameBar( - userInfo.userProfile?.nickName ?? ""))!; + userInfo.userProfile?.nickName ?? "", + widget.smallCardMode))!; case ProfileWidgetEnum.userAccountBar: return (customBuilder?.userAccountBar != null ? customBuilder ?.userAccountBar!(userInfo.userProfile?.userID ?? "") : TIMUIKitProfileWidget.userAccountBar( - userInfo.userProfile?.userID ?? ""))!; + userInfo.userProfile?.userID ?? "", + widget.smallCardMode))!; case ProfileWidgetEnum.signatureBar: return (customBuilder?.signatureBar != null ? customBuilder?.signatureBar!( userInfo.userProfile?.selfSignature ?? "") : TIMUIKitProfileWidget.signatureBar( - userInfo.userProfile?.selfSignature ?? ""))!; + userInfo.userProfile?.selfSignature ?? "", + widget.smallCardMode))!; case ProfileWidgetEnum.genderBar: return (customBuilder?.genderBar != null ? customBuilder ?.genderBar!(userInfo.userProfile?.gender ?? 0) : TIMUIKitProfileWidget.genderBar( - userInfo.userProfile?.gender ?? 0))!; + userInfo.userProfile?.gender ?? 0, + widget.smallCardMode))!; case ProfileWidgetEnum.birthdayBar: return (customBuilder?.birthdayBar != null ? customBuilder ?.birthdayBar!(userInfo.userProfile?.birthday) : TIMUIKitProfileWidget.birthdayBar( - userInfo.userProfile?.birthday))!; + userInfo.userProfile?.birthday, + widget.smallCardMode))!; case ProfileWidgetEnum.addAndDeleteArea: if (isSelf) { return Container(); @@ -347,19 +381,37 @@ class _TIMUIKitProfileState extends TIMUIKitState { value.friendType, isMute, ) - : TIMUIKitProfileWidget.addAndDeleteArea( - userInfo, - conversation, - value.friendType, - isMute, - model.isAddToBlackList ?? false, - theme, - handleAddFriend, - handleDeleteFriend))!; + : isDesktopScreen + ? TIMUIKitProfileWidget.addAndDeleteAreaWide( + userInfo, + conversation, + value.friendType, + isMute, + model.isAddToBlackList ?? false, + theme, + handleAddFriend, + handleDeleteFriend, + widget.smallCardMode) + : TIMUIKitProfileWidget.addAndDeleteArea( + userInfo, + conversation, + value.friendType, + isMute, + model.isAddToBlackList ?? false, + theme, + handleAddFriend, + handleDeleteFriend, + widget.smallCardMode))!; case ProfileWidgetEnum.operationDivider: return (customBuilder?.operationDivider != null ? customBuilder?.operationDivider!() - : TIMUIKitProfileWidget.operationDivider())!; + : TIMUIKitProfileWidget.operationDivider( + color: theme.weakDividerColor, + height: isDesktopScreen ? 1 : 10, + margin: isDesktopScreen + ? EdgeInsets.symmetric( + vertical: widget.smallCardMode ? 4 : 20) + : null))!; case ProfileWidgetEnum.remarkBar: if (!isFriend) { return Container(); @@ -368,7 +420,10 @@ class _TIMUIKitProfileState extends TIMUIKitState { ? customBuilder?.remarkBar!( userInfo.friendRemark ?? "", handleTapRemarkBar) : TIMUIKitProfileWidget.remarkBar( - userInfo.friendRemark ?? "", handleTapRemarkBar))!; + context, + userInfo.friendRemark ?? "", + handleTapRemarkBar, + widget.smallCardMode))!; case ProfileWidgetEnum.customBuilderOne: return (customBuilder?.customBuilderOne != null ? customBuilder?.customBuilderOne!( @@ -407,10 +462,8 @@ class _TIMUIKitProfileState extends TIMUIKitState { } if (widget.builder != null) { - return profilePage( - child: widget.builder!( - context, userInfo, conversation, value.friendType, isMute), - ); + return widget.builder!( + context, userInfo, conversation, value.friendType, isMute); } else if (widget.profileWidgetsOrder != null) { return profilePage( child: Column( diff --git a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart index c3c932d..2f55c91 100644 --- a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart +++ b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; class TIMUIKitOperationItem extends TIMUIKitStatelessWidget { final String operationName; @@ -10,89 +11,195 @@ class TIMUIKitOperationItem extends TIMUIKitStatelessWidget { /// shows on the second line final String? operationDescription; final bool? operationValue; - final bool isRightIcon; - /// if allow to show arrow to right - final bool showArrowRightIcon; + /// Is show allow edit status, while a right icon shows on mobile, and `showAllowEditStatus` shows on desktop. + final bool showAllowEditStatus; + + /// Used on wide screen. + final String? wideEditText; + + /// Used on wide screen. + final bool isEmpty; /// the operationText widget for replacement, for developers to define what to do final Widget? operationRightWidget; final String type; final void Function(bool newValue)? onSwitchChange; + final Key? itemBoxKey; + final bool isUseCheckedBoxOnWide; + + /// Is use the small card mode on Desktop. Usually shows on the Chat page. + final bool smallCardMode; TIMUIKitOperationItem( {Key? key, + this.wideEditText, + this.itemBoxKey, this.operationDescription, + required this.isEmpty, required this.operationName, + this.smallCardMode = false, this.operationValue, this.type = "arrow", + this.isUseCheckedBoxOnWide = false, this.onSwitchChange, this.operationRightWidget, - this.showArrowRightIcon = true, - this.isRightIcon = true}) + this.showAllowEditStatus = true}) : super(key: key); @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Container( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - margin: const EdgeInsets.only(bottom: 1), + padding: isDesktopScreen + ? EdgeInsets.symmetric( + horizontal: isUseCheckedBoxOnWide ? 6 : 16, + vertical: smallCardMode ? 0 : 4) + : const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + margin: isDesktopScreen ? null : const EdgeInsets.only(bottom: 1), color: Colors.white, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + child: (isDesktopScreen && isUseCheckedBoxOnWide) + ? Row( children: [ - Text(operationName), - if (operationDescription != null) - Text( - operationDescription!, - style: - TextStyle(color: theme.weakTextColor, fontSize: 12), - ) - ], - ), - ), - type == "switch" - ? Transform.scale( + Transform.scale( scale: 0.8, - child: CupertinoSwitch( - value: operationValue ?? false, - onChanged: onSwitchChange, - activeColor: theme.primaryColor, - ), - ) - : Row( - mainAxisAlignment: MainAxisAlignment.end, + child: Checkbox( + fillColor: MaterialStateProperty.all(theme.primaryColor), + value: operationValue ?? false, + onChanged: (val) { + if (onSwitchChange != null) { + onSwitchChange!(val ?? false); + } + }), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, children: [ - Transform.scale( + Text( + operationName, + style: const TextStyle(fontSize: 14), + ), + if (operationDescription != null) + Text( + operationDescription!, + style: + TextStyle(color: theme.weakTextColor, fontSize: 12), + ) + ], + )), + ], + ) + : Row( + mainAxisAlignment: isDesktopScreen + ? MainAxisAlignment.start + : MainAxisAlignment.spaceBetween, + children: [ + if (isDesktopScreen) + SizedBox( + width: 130, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + operationName, + style: TextStyle( + color: + isDesktopScreen ? hexToColor("7f7f7f") : null), + ), + if (operationDescription != null) + Text( + operationDescription!, + style: TextStyle( + color: theme.weakTextColor, fontSize: 12), + ) + ], + ), + ), + if (!isDesktopScreen) + Expanded( + child: SizedBox( + width: 130, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + operationName, + style: TextStyle( + color: + isDesktopScreen ? hexToColor("7f7f7f") : null), + ), + if (operationDescription != null) + Text( + operationDescription!, + style: TextStyle( + color: theme.weakTextColor, fontSize: 12), + ) + ], + ), + )), + if (type == "switch") + Transform.scale( + key: itemBoxKey, + scale: 0.8, + child: CupertinoSwitch( + value: operationValue ?? false, + onChanged: onSwitchChange, + activeColor: theme.primaryColor, + ), + ), + if (type != "switch" && !isDesktopScreen) + Transform.scale( + scale: 0, + child: CupertinoSwitch( + value: false, + onChanged: onSwitchChange, + ), + ), + (type != "switch" && + isDesktopScreen && + showAllowEditStatus && + isEmpty) + ? MouseRegion( + key: itemBoxKey, + child: Text( + wideEditText ?? TIM_t("编辑"), + style: TextStyle(color: theme.weakTextColor), + ), + ) + : Container( + width: 0, + ), + if (type != "switch") + Expanded( + child: Row( + mainAxisAlignment: isDesktopScreen + ? MainAxisAlignment.start + : MainAxisAlignment.end, + children: [Expanded(child: operationRightWidget ?? const Text(""))], + )), + (type != "switch" && !isDesktopScreen && showAllowEditStatus) + ? const Icon(Icons.keyboard_arrow_right) + : Container( + width: 0, + ), + if (type != "switch" && isDesktopScreen) + SizedBox( + width: 0, + child: Transform.scale( scale: 0, child: CupertinoSwitch( value: false, onChanged: onSwitchChange, ), ), - ConstrainedBox( - constraints: BoxConstraints( - maxWidth: MediaQuery.of(context).size.width / 1.6, - ), - child: operationRightWidget ?? const Text(""), - ), - isRightIcon - ? showArrowRightIcon - ? const Icon(Icons.keyboard_arrow_right) - : Container( - width: 10, - ) - : Container(), - ], - ), - ], - ), + ), + ], + ), ); } } diff --git a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart new file mode 100644 index 0000000..6e40ca1 --- /dev/null +++ b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card.dart @@ -0,0 +1,50 @@ +// ignore_for_file: deprecated_member_use_from_same_package + +import 'package:flutter/cupertino.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_narrow.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_wide.dart'; + +class TIMUIKitProfileUserInfoCard extends StatelessWidget { + /// User info + final V2TimUserFullInfo? userInfo; + final bool isJumpToPersonalProfile; + final VoidCallback? onClickAvatar; + + /// If shows the arrow icon on the right + final bool showArrowRightIcon; + + const TIMUIKitProfileUserInfoCard( + {Key? key, + this.userInfo, + @Deprecated("This info card can no longer navigate to default personal profile page automatically, please deal with it manually.") + this.isJumpToPersonalProfile = false, + this.showArrowRightIcon = false, + this.onClickAvatar}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return TUIKitScreenUtils.getDeviceWidget( + defaultWidget: TIMUIKitProfileUserInfoCardNarrow( + userInfo: userInfo, + isJumpToPersonalProfile: isJumpToPersonalProfile, + showArrowRightIcon: showArrowRightIcon, + onClickAvatar: onClickAvatar, + ), + desktopWidget: TIMUIKitProfileUserInfoCardWide( + userInfo: userInfo, + onClickAvatar: onClickAvatar, + isJumpToPersonalProfile: isJumpToPersonalProfile, + showArrowRightIcon: showArrowRightIcon, + ), + mobileWidget: TIMUIKitProfileUserInfoCardNarrow( + userInfo: userInfo, + onClickAvatar: onClickAvatar, + isJumpToPersonalProfile: isJumpToPersonalProfile, + showArrowRightIcon: showArrowRightIcon, + ), + ); + } +} diff --git a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card.dart b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_narrow.dart similarity index 78% rename from lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card.dart rename to lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_narrow.dart index 3feccbf..7f65f4c 100644 --- a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card.dart +++ b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_narrow.dart @@ -5,16 +5,18 @@ import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; -class TIMUIKitProfileUserInfoCard extends TIMUIKitStatelessWidget { +class TIMUIKitProfileUserInfoCardNarrow extends TIMUIKitStatelessWidget { /// User info final V2TimUserFullInfo? userInfo; final bool isJumpToPersonalProfile; + final VoidCallback? onClickAvatar; /// If shows the arrow icon on the right final bool showArrowRightIcon; - TIMUIKitProfileUserInfoCard( + TIMUIKitProfileUserInfoCardNarrow( {Key? key, + this.onClickAvatar, this.userInfo, @Deprecated("This info card can no longer navigate to default personal profile page automatically, please deal with it manually.") this.isJumpToPersonalProfile = false, @@ -43,11 +45,14 @@ class TIMUIKitProfileUserInfoCard extends TIMUIKitStatelessWidget { SizedBox( width: 48, height: 48, - child: Avatar( - faceUrl: faceUrl, - isShowBigWhenClick: true, - showName: showName ?? "", - type: 1, + child: GestureDetector( + onTap: onClickAvatar, + child: Avatar( + faceUrl: faceUrl, + isShowBigWhenClick: onClickAvatar == null, + showName: showName ?? "", + type: 1, + ), ), ), const SizedBox( @@ -59,10 +64,9 @@ class TIMUIKitProfileUserInfoCard extends TIMUIKitStatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( - child: Text( + child: SelectableText( showName ?? "", style: const TextStyle(fontSize: 18, color: Colors.black), - softWrap: true, ), ), Container( @@ -71,16 +75,18 @@ class TIMUIKitProfileUserInfoCard extends TIMUIKitStatelessWidget { children: [ Text( "ID: ", - style: TextStyle(fontSize: 13, color: theme.weakTextColor), + style: + TextStyle(fontSize: 13, color: theme.weakTextColor), ), SelectableText( userInfo?.userID ?? "", - style: TextStyle(fontSize: 13, color: theme.weakTextColor), + style: + TextStyle(fontSize: 13, color: theme.weakTextColor), ), ], ), ), - Text(signatureText, + SelectableText(signatureText, style: TextStyle(fontSize: 13, color: theme.weakTextColor)) ], ), diff --git a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_wide.dart b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_wide.dart new file mode 100644 index 0000000..2e74373 --- /dev/null +++ b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_wide.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:tencent_im_base/tencent_im_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; + +class TIMUIKitProfileUserInfoCardWide extends TIMUIKitStatelessWidget { + /// User info + final V2TimUserFullInfo? userInfo; + final bool isJumpToPersonalProfile; + final VoidCallback? onClickAvatar; + + /// If shows the arrow icon on the right + final bool showArrowRightIcon; + + TIMUIKitProfileUserInfoCardWide( + {Key? key, + this.userInfo, + this.onClickAvatar, + @Deprecated("This info card can no longer navigate to default personal profile page automatically, please deal with it manually.") + this.isJumpToPersonalProfile = false, + this.showArrowRightIcon = false}) + : super(key: key); + + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final TUITheme theme = value.theme; + final faceUrl = userInfo?.faceUrl ?? ""; + final nickName = userInfo?.nickName ?? ""; + final signature = userInfo?.selfSignature; + final showName = nickName != "" ? nickName : userInfo?.userID; + + return Container( + padding: const EdgeInsets.only(bottom: 10, left: 16, right: 16), + color: Colors.white, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: SelectableText( + showName ?? "", + style: const TextStyle(fontSize: 20, color: Colors.black), + ), + margin: const EdgeInsets.only(right: 10), + ), + Row( + children: [ + Text( + "ID: ", + style: + TextStyle(fontSize: 12, color: theme.weakTextColor), + ), + Expanded(child: SelectableText( + userInfo?.userID ?? "", + style: + TextStyle(fontSize: 12, color: theme.weakTextColor), + )), + ], + ), + if (signature != null) + Container( + margin: const EdgeInsets.only(top: 18), + child: SelectableText(signature, + style: TextStyle( + fontSize: 14, color: hexToColor("7f7f7f"))), + ) + ], + ), + ), + Row( + children: [ + const SizedBox( + width: 40, + ), + SizedBox( + width: 80, + height: 80, + child: InkWell( + onTap: onClickAvatar, + child: Avatar( + faceUrl: faceUrl, + isShowBigWhenClick: onClickAvatar == null, + showName: showName ?? "", + type: 1, + ), + ), + ), + showArrowRightIcon + ? const Icon(Icons.keyboard_arrow_right) + : Container() + ], + ) + ], + ), + ); + } +} diff --git a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_widget.dart b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_widget.dart index 9904853..7576bb3 100644 --- a/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_widget.dart +++ b/lib/ui/views/TIMUIKitProfile/widget/tim_uikit_profile_widget.dart @@ -1,36 +1,63 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_class.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; class TIMUIKitProfileWidget extends TIMUIKitClass { - static Widget operationDivider() { - return const SizedBox( - height: 10, + static final bool isDesktopScreen = + TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop; + + static Widget operationDivider( + {Color? color, double? height, EdgeInsetsGeometry? margin}) { + return Container( + color: color, + margin: margin, + height: height ?? 10, ); } /// Remarks - static Widget remarkBar(String remark, Function()? handleTap) { + static Widget remarkBar( + BuildContext context, + String remark, + Function({Offset? offset, String? initText})? handleTap, + bool smallCardMode) { + final GlobalKey key = GlobalKey(); return InkWell( - onTap: () { + onTapDown: (details) { if (handleTap != null) { - handleTap(); + handleTap( + offset: Offset( + min(details.globalPosition.dx, + MediaQuery.of(context).size.width - 400), + min(details.globalPosition.dy, + MediaQuery.of(context).size.height - 100)), + initText: remark); } }, child: TIMUIKitOperationItem( + smallCardMode: smallCardMode, + itemBoxKey: key, + isEmpty: remark.isEmpty, + wideEditText: TIM_t("设置备注名"), operationName: TIM_t("备注名"), - operationRightWidget: Text(remark), + operationRightWidget: + Text(remark, textAlign: isDesktopScreen ? null : TextAlign.end), ), ); } /// add to block list - static Widget addToBlackListBar( - bool value, BuildContext context, Function(bool value)? onChanged) { + static Widget addToBlackListBar(bool value, BuildContext context, + Function(bool value)? onChanged, bool smallCardMode) { return TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: false, operationName: TIM_t("加入黑名单"), type: "switch", operationValue: value, @@ -43,9 +70,11 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { } /// pin the conversation to the top - static Widget pinConversationBar( - bool value, BuildContext context, Function(bool value)? onChanged) { + static Widget pinConversationBar(bool value, BuildContext context, + Function(bool value)? onChanged, bool smallCardMode) { return TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: false, operationName: TIM_t("置顶聊天"), type: "switch", operationValue: value, @@ -58,9 +87,11 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { } /// message disturb - static Widget messageDisturb( - BuildContext context, bool isDisturb, Function(bool value)? onChanged) { + static Widget messageDisturb(BuildContext context, bool isDisturb, + Function(bool value)? onChanged, bool smallCardMode) { return TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: false, operationName: TIM_t("消息免打扰"), type: "switch", operationValue: isDisturb, @@ -72,25 +103,33 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { ); } - static Widget operationItem({ - required String operationName, - required String type, - bool? operationValue, - String? operationText, - void Function(bool newValue)? onSwitchChange, - }) { + static Widget operationItem( + {required String operationName, + required String type, + bool? operationValue, + String? operationText, + required bool isEmpty, + void Function(bool newValue)? onSwitchChange, + required bool smallCardMode}) { return TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: isEmpty, operationName: operationName, type: type, - operationRightWidget: Text(operationText ?? ""), + operationRightWidget: Text(operationText ?? "", + textAlign: isDesktopScreen ? null : TextAlign.end), operationValue: operationValue, onSwitchChange: onSwitchChange, ); } /// find history message - static Widget searchBar(BuildContext context, V2TimConversation conversation, - {Function()? handleTap}) { + static Widget searchBar( + BuildContext context, + V2TimConversation conversation, + bool smallCardMode, { + Function()? handleTap, + }) { return InkWell( onTap: () { if (handleTap != null) { @@ -98,24 +137,29 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { } }, child: TIMUIKitOperationItem( + isEmpty: true, + wideEditText: TIM_t("立即搜索"), operationName: TIM_t("查找聊天内容"), ), ); } /// portrait - static Widget portraitBar(Widget portraitWidget) { + static Widget portraitBar(Widget portraitWidget, bool smallCardMode) { return SizedBox( child: TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: false, operationName: TIM_t("头像"), operationRightWidget: portraitWidget, - showArrowRightIcon: false, + showAllowEditStatus: false, ), ); } /// defaultPortraitWidget - static Widget defaultPortraitWidget(V2TimUserFullInfo? userInfo) { + static Widget defaultPortraitWidget( + V2TimUserFullInfo? userInfo, bool smallCardMode) { return SizedBox( width: 48, height: 48, @@ -130,40 +174,52 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { } /// nickname - static Widget nicknameBar(String nickName) { + static Widget nicknameBar( + String nickName, + bool smallCardMode, + ) { return SizedBox( child: TIMUIKitOperationItem( - showArrowRightIcon: false, + smallCardMode: smallCardMode, + isEmpty: nickName.isEmpty, + showAllowEditStatus: false, operationName: TIM_t("昵称"), - operationRightWidget: Text(nickName), + operationRightWidget: + Text(nickName, textAlign: isDesktopScreen ? null : TextAlign.end), ), ); } /// user account - static Widget userAccountBar(String userNum) { + static Widget userAccountBar(String userNum, bool smallCardMode) { return SizedBox( child: TIMUIKitOperationItem( - showArrowRightIcon: false, + smallCardMode: smallCardMode, + isEmpty: false, + showAllowEditStatus: false, operationName: TIM_t("账号"), - operationRightWidget: SelectableText(userNum), + operationRightWidget: SelectableText(userNum, + textAlign: isDesktopScreen ? null : TextAlign.end), ), ); } /// signature - static Widget signatureBar(String signature) { + static Widget signatureBar(String signature, bool smallCardMode) { return SizedBox( child: TIMUIKitOperationItem( - showArrowRightIcon: false, + smallCardMode: smallCardMode, + isEmpty: false, + showAllowEditStatus: false, operationName: TIM_t("个性签名"), - operationRightWidget: Text(signature), + operationRightWidget: + Text(signature, textAlign: isDesktopScreen ? null : TextAlign.end), ), ); } /// gender - static Widget genderBar(int gender) { + static Widget genderBar(int gender, bool smallCardMode) { Map genderMap = { 0: TIM_t("未填写"), 1: TIM_t("男"), @@ -171,15 +227,18 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { }; return SizedBox( child: TIMUIKitOperationItem( - showArrowRightIcon: false, + smallCardMode: smallCardMode, + isEmpty: false, + showAllowEditStatus: false, operationName: TIM_t("性别"), - operationRightWidget: Text(genderMap[gender]), + operationRightWidget: Text(genderMap[gender], + textAlign: isDesktopScreen ? null : TextAlign.end), ), ); } /// gender - static Widget genderBarWithArrow(int gender) { + static Widget genderBarWithArrow(int gender, bool smallCardMode) { Map genderMap = { 0: TIM_t("未填写"), 1: TIM_t("男"), @@ -187,48 +246,51 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { }; return SizedBox( child: TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: false, operationName: TIM_t("性别"), - operationRightWidget: Text(genderMap[gender]), + operationRightWidget: Text(genderMap[gender], + textAlign: isDesktopScreen ? null : TextAlign.end), ), ); } /// birthday - static Widget birthdayBar(int? birthday) { + static Widget birthdayBar(int? birthday, bool smallCardMode) { try { final date = DateTime.parse(birthday.toString()); DateFormat formatter = DateFormat('yyyy-MM-dd'); - return InkWell( - onTap: () {}, - child: TIMUIKitOperationItem( - showArrowRightIcon: false, - operationName: TIM_t("生日"), - operationRightWidget: Text(formatter.format(date)), - ), + return TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: false, + showAllowEditStatus: false, + operationName: TIM_t("生日"), + operationRightWidget: Text(formatter.format(date), + textAlign: isDesktopScreen ? null : TextAlign.end), ); } catch (e) { - return InkWell( - onTap: () {}, - child: TIMUIKitOperationItem( - showArrowRightIcon: false, - operationName: TIM_t("生日"), - operationRightWidget: Text(TIM_t("未填写")), - ), + return TIMUIKitOperationItem( + smallCardMode: smallCardMode, + isEmpty: false, + showAllowEditStatus: false, + operationName: TIM_t("生日"), + operationRightWidget: + Text(TIM_t("未填写"), textAlign: isDesktopScreen ? null : TextAlign.end), ); } } /// default button area static Widget addAndDeleteArea( - V2TimFriendInfo friendInfo, - V2TimConversation conversation, - int friendType, - bool isDisturb, - bool isBlocked, - TUITheme theme, - VoidCallback handleAddFriend, - VoidCallback handleDeleteFriend, - ) { + V2TimFriendInfo friendInfo, + V2TimConversation conversation, + int friendType, + bool isDisturb, + bool isBlocked, + TUITheme theme, + VoidCallback handleAddFriend, + VoidCallback handleDeleteFriend, + bool smallCardMode) { _buildDeleteFriend(V2TimConversation conversation, theme) { return InkWell( onTap: () { @@ -279,4 +341,75 @@ class TIMUIKitProfileWidget extends TIMUIKitClass { ], ); } + + static Widget wideButton({ + required VoidCallback onPressed, + required String text, + required Color color, + required bool smallCardMode, + EdgeInsets? margin, + }) { + return Container( + margin: margin ?? const EdgeInsets.symmetric(vertical: 10), + child: smallCardMode + ? OutlinedButton( + onPressed: onPressed, + child: Text( + text, + style: TextStyle(color: color), + ), + style: ButtonStyle( + minimumSize: + MaterialStateProperty.all(const Size(160, 40)), + )) + : ElevatedButton( + onPressed: onPressed, + child: Text(text), + style: ButtonStyle( + minimumSize: + MaterialStateProperty.all(const Size(180, 46)), + backgroundColor: MaterialStateProperty.all(color)), + ), + ); + } + + /// default button area + static Widget addAndDeleteAreaWide( + V2TimFriendInfo friendInfo, + V2TimConversation conversation, + int friendType, + bool isDisturb, + bool isBlocked, + TUITheme theme, + VoidCallback handleAddFriend, + VoidCallback handleDeleteFriend, + bool smallCardMode, + ) { + _buildDeleteFriend(V2TimConversation conversation, theme) { + return wideButton( + smallCardMode: smallCardMode, + onPressed: () { + handleDeleteFriend(); + }, + color: theme.cautionColor ?? Colors.red, + text: TIM_t("清除好友"), + ); + } + + _buildAddOperation() { + return wideButton( + smallCardMode: smallCardMode, + onPressed: handleAddFriend, + color: theme.primaryColor ?? hexToColor("3e4b67"), + text: TIM_t("加为好友"), + ); + } + + return Column( + children: [ + if (friendType != 0) _buildDeleteFriend(conversation, theme), + if (friendType == 0 && !isBlocked) _buildAddOperation() + ], + ); + } } diff --git a/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input.dart b/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input.dart index 5a4591d..e63f5e3 100644 --- a/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input.dart +++ b/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input.dart @@ -1,12 +1,9 @@ import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; - - +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; - class TIMUIKitSearchInput extends StatefulWidget { final ValueChanged onChange; final String? initValue; @@ -50,30 +47,38 @@ class TIMUIKitSearchInputState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return Container( - height: 64, - padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), - decoration: BoxDecoration(color: theme.primaryColor, boxShadow: [ - BoxShadow( - color: theme.weakBackgroundColor ?? hexToColor("E6E9EB"), - offset: const Offset(0.0, 2.0), - ) - ]), + // height: 64, + padding: EdgeInsets.fromLTRB(16, isDesktopScreen ? 16 : 8, 16, 16), + margin: isDesktopScreen ? const EdgeInsets.only(bottom: 2) : null, + decoration: BoxDecoration( + color: isDesktopScreen + ? theme.wideBackgroundColor + : theme.primaryColor, + boxShadow: [ + BoxShadow( + color: theme.weakBackgroundColor ?? hexToColor("E6E9EB"), + offset: const Offset(0.0, 2.0), + ) + ] + ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( - child: SizedBox( - height: 36, + child: ConstrainedBox( + constraints: BoxConstraints(maxHeight: isDesktopScreen ? 30 : 36), child: TextField( autofocus: widget.isAutoFocus ?? true, onChanged: (value) async { final trimValue = value.trim(); final isEmpty = trimValue.isEmpty; - setState(() { - isEmptyInput = isEmpty ? true : false; - }); + if(isEmpty != isEmptyInput){ + setState(() { + isEmptyInput = isEmpty ? true : false; + }); + } widget.onChange(trimValue); }, keyboardType: TextInputType.text, @@ -83,13 +88,18 @@ class TIMUIKitSearchInputState extends TIMUIKitState { focusNode: widget.focusNode, controller: textEditingController, textAlignVertical: TextAlignVertical.center, + textAlign: TextAlign.start, + style: isDesktopScreen ? const TextStyle( + fontSize: 12 + ) : null, decoration: InputDecoration( - border: InputBorder.none, + contentPadding: const EdgeInsets.all(0), + border: const OutlineInputBorder(borderSide: BorderSide.none), hintStyle: TextStyle( - fontSize: 14, + fontSize: isDesktopScreen ? 12 : 14, color: hexToColor("CCCCCC"), ), - fillColor: Colors.white, + fillColor: isDesktopScreen ? hexToColor("f3f3f4") : Colors.white, filled: true, isDense: true, hintText: TIM_t("搜索"), @@ -120,7 +130,7 @@ class TIMUIKitSearchInputState extends TIMUIKitState { ), ), )), - Container( + if(!isDesktopScreen) Container( margin: const EdgeInsets.fromLTRB(10, 0, 0, 0), child: GestureDetector( onTap: () { diff --git a/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_item.dart b/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_item.dart index 5d49743..4a5ed9f 100644 --- a/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_item.dart +++ b/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_item.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/tim_uikit_search_item_wide.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; @@ -51,57 +53,67 @@ class TIMUIKitSearchItem extends TIMUIKitStatelessWidget { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - return GestureDetector( - onTap: onClick, - child: Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide(color: hexToColor("DBDBDB"), width: 0.5))), - padding: const EdgeInsets.fromLTRB(0, 12, 0, 12), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: 40, - height: 40, - child: Stack( - fit: StackFit.expand, - clipBehavior: Clip.none, - children: [Avatar(faceUrl: faceUrl, showName: showName)], + return TUIKitScreenUtils.getDeviceWidget( + defaultWidget: GestureDetector( + onTap: onClick, + child: Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: hexToColor("DBDBDB"), width: 0.5))), + padding: const EdgeInsets.fromLTRB(0, 12, 0, 12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 40, + height: 40, + child: Stack( + fit: StackFit.expand, + clipBehavior: Clip.none, + children: [Avatar(faceUrl: faceUrl, showName: showName)], + ), ), - ), - Expanded( - child: Container( - margin: const EdgeInsets.only(left: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - // height: 24, - padding: const EdgeInsets.symmetric(vertical: 2), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - lineOne, - style: const TextStyle( - color: Colors.black, - fontSize: 18.0, - fontWeight: FontWeight.w400), - ), - _renderLineOneRight(lineOneRight, theme), - ], + Expanded( + child: Container( + margin: const EdgeInsets.only(left: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + // height: 24, + padding: const EdgeInsets.symmetric(vertical: 2), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + lineOne, + style: TextStyle( + color: theme.darkTextColor, + fontSize: 18.0, + fontWeight: FontWeight.w400), + ), + _renderLineOneRight(lineOneRight, theme), + ], + ), ), - ), - _renderLineTwo(lineTwo, theme), - ], - ), - )) - ], + _renderLineTwo(lineTwo, theme), + ], + ), + )) + ], + ), ), ), + desktopWidget: TIMUIKitSearchWideItem( + lineOneRight: lineOneRight, + key: key, + lineTwo: lineTwo, + onClick: onClick, + faceUrl: faceUrl, + showName: showName, + lineOne: lineOne), ); } } diff --git a/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_showAll.dart b/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_showAll.dart index 590bb2c..e8837af 100644 --- a/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_showAll.dart +++ b/lib/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_showAll.dart @@ -5,6 +5,7 @@ import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; class TIMUIKitSearchShowALl extends TIMUIKitStatelessWidget { final String textShow; @@ -20,7 +21,8 @@ class TIMUIKitSearchShowALl extends TIMUIKitStatelessWidget { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { - return GestureDetector( + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + return InkWell( onTap: onClick, child: Container( decoration: BoxDecoration( @@ -47,9 +49,9 @@ class TIMUIKitSearchShowALl extends TIMUIKitStatelessWidget { padding: const EdgeInsets.symmetric(vertical: 2), child: Text( textShow, - style: const TextStyle( + style: TextStyle( color: Colors.black, - fontSize: 16.0, + fontSize: isDesktopScreen ? 14 : 16.0, fontWeight: FontWeight.w400), ), ), diff --git a/lib/ui/views/TIMUIKitSearch/tim_uikit_search.dart b/lib/ui/views/TIMUIKitSearch/tim_uikit_search.dart index 6d3f3b3..24c355c 100644 --- a/lib/ui/views/TIMUIKitSearch/tim_uikit_search.dart +++ b/lib/ui/views/TIMUIKitSearch/tim_uikit_search.dart @@ -3,7 +3,6 @@ import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_search_view_model.dart'; - import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_indicator.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/tim_uikit_search_friend.dart'; @@ -31,6 +30,8 @@ class TIMUIKitSearch extends StatefulWidget { final Function(V2TimConversation conversation, String initKeyword)? onEnterSearchInConversation; + final VoidCallback? onBack; + final bool? isAutoFocus; const TIMUIKitSearch( @@ -41,7 +42,8 @@ class TIMUIKitSearch extends StatefulWidget { @Deprecated("You are supposed to use [onEnterSearchInConversation], though the effects are the same.") this.onEnterConversation, this.isAutoFocus = true, - this.onEnterSearchInConversation}) + this.onEnterSearchInConversation, + this.onBack}) : super(key: key); @override @@ -106,29 +108,45 @@ class TIMUIKitSearchState extends TIMUIKitState { controller: textEditingController, prefixIcon: Icon( Icons.search, + size: 16, color: hexToColor("979797"), ), ), Expanded( - child: SingleChildScrollView( - child: Column( - children: [ - if (friendResultList.isEmpty || - !(searchTypes.contains(SearchType.contact)) && - (groupList.isEmpty || - !(searchTypes.contains(SearchType.group))) && - (totalMsgCount == 0 || - !(searchTypes.contains(SearchType.history)))) - TIMUIKitSearchIndicator( - typeList: searchTypes, - onChange: (list) { - setState(() { - searchTypes = list; - }); - }, - ), - if (searchTypes.contains(SearchType.contact)) - TIMUIKitSearchFriend( + child: GestureDetector( + child: SingleChildScrollView( + child: Column( + children: [ + if ((friendResultList.isEmpty || + !(searchTypes.contains(SearchType.contact))) && + (groupList.isEmpty || + !(searchTypes + .contains(SearchType.group))) && + (totalMsgCount == 0 || + !(searchTypes + .contains(SearchType.history)))) + TIMUIKitSearchIndicator( + typeList: searchTypes, + onChange: (list) { + setState(() { + searchTypes = list; + }); + }, + ), + if (searchTypes.contains(SearchType.contact)) + TIMUIKitSearchFriend( + onTapConversation: (conversation, message) { + focusNode.unfocus(); + Future.delayed( + const Duration(milliseconds: 100), () { + widget.onTapConversation( + conversation, message); + }); + }, + friendResultList: friendResultList), + if (searchTypes.contains(SearchType.group)) + TIMUIKitSearchGroup( + groupList: groupList, onTapConversation: (conversation, message) { focusNode.unfocus(); Future.delayed(const Duration(milliseconds: 100), @@ -136,37 +154,33 @@ class TIMUIKitSearchState extends TIMUIKitState { widget.onTapConversation(conversation, message); }); }, - friendResultList: friendResultList), - if (searchTypes.contains(SearchType.group)) - TIMUIKitSearchGroup( - groupList: groupList, - onTapConversation: (conversation, message) { - focusNode.unfocus(); - Future.delayed(const Duration(milliseconds: 100), - () { - widget.onTapConversation(conversation, message); - }); - }, - ), - if (searchTypes.contains(SearchType.history)) - TIMUIKitSearchMsg( - onTapConversation: widget.onTapConversation, - keyword: textEditingController.text, - totalMsgCount: totalMsgCount, - msgList: msgList, - onEnterConversation: - (V2TimConversation conversation, String keyword) { - if (widget.onEnterSearchInConversation != null) { - widget.onEnterSearchInConversation!( - conversation, keyword); - } else if (widget.onEnterConversation != null) { - widget.onEnterConversation!( - conversation, keyword); - } - }, - ) - ], + ), + if (searchTypes.contains(SearchType.history)) + TIMUIKitSearchMsg( + onTapConversation: widget.onTapConversation, + keyword: textEditingController.text, + totalMsgCount: totalMsgCount, + msgList: msgList, + onEnterConversation: + (V2TimConversation conversation, + String keyword) { + if (widget.onEnterSearchInConversation != null) { + widget.onEnterSearchInConversation!( + conversation, keyword); + } else if (widget.onEnterConversation != null) { + widget.onEnterConversation!( + conversation, keyword); + } + }, + ), + ], + ), ), + onTap: () { + if (widget.onBack != null) { + widget.onBack!(); + } + }, )) ], ), diff --git a/lib/ui/views/TIMUIKitSearch/tim_uikit_search_item_wide.dart b/lib/ui/views/TIMUIKitSearch/tim_uikit_search_item_wide.dart new file mode 100644 index 0000000..4e27c91 --- /dev/null +++ b/lib/ui/views/TIMUIKitSearch/tim_uikit_search_item_wide.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; + +import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; + +class TIMUIKitSearchWideItem extends TIMUIKitStatelessWidget { + final String faceUrl; + final String showName; + final String lineOne; + final String? lineOneRight; + final String? lineTwo; + final VoidCallback? onClick; + + TIMUIKitSearchWideItem( + {Key? key, + required this.faceUrl, + required this.showName, + required this.lineOne, + this.lineTwo, + this.lineOneRight, + this.onClick}) + : super(key: key); + + _renderLineOneRight(String? text, TUITheme theme) { + if (text != null) { + return Text(text, + style: TextStyle( + fontSize: 10, + color: theme.weakTextColor, + )); + } else { + return Container(); + } + } + + _renderLineTwo(String? text, TUITheme theme) { + return (text != null) + ? Container( + margin: const EdgeInsets.only(top: 0), + child: SelectableText( + text, + style: TextStyle( + color: theme.weakTextColor, height: 1.5, fontSize: 12), + ), + ) + : Container( + height: 0, + ); + } + + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final TUITheme theme = value.theme; + + return Material( + color: Colors.white, + child: InkWell( + onTap: onClick, + child: Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: hexToColor("DBDBDB"), width: 0.5))), + padding: const EdgeInsets.fromLTRB(0, 12, 0, 12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 30, + height: 30, + child: Avatar(faceUrl: faceUrl, showName: showName, isShowBigWhenClick: false,), + ), + Expanded( + child: Container( + margin: const EdgeInsets.only(left: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + // height: 24, + padding: const EdgeInsets.symmetric(vertical: 2), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded(child: Text( + lineOne, + style: TextStyle( + color: theme.darkTextColor, + fontSize: 14.0, + fontWeight: FontWeight.w400), + )), + _renderLineOneRight(lineOneRight, theme), + ], + ), + ), + _renderLineTwo(lineTwo, theme), + ], + ), + )) + ], + ), + ), + ), + ); + } +} diff --git a/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg.dart b/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg.dart index 2d4ae79..3b840d1 100644 --- a/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg.dart +++ b/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/conversation/conversation_services.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_search_view_model.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_item.dart'; @@ -47,13 +48,19 @@ class TIMUIKitSearchMsg extends TIMUIKitStatelessWidget { if (msgList.isNotEmpty) { return TIMUIKitSearchFolder(folderName: TIM_t("聊天记录"), children: [ ...msgList.map((conv) { - V2TimConversation conversation = _conversationList[ - _conversationList.indexWhere( - (item) => item!.conversationID == conv?.conversationID)]!; + V2TimConversation? conversation; + final index = _conversationList.indexWhere( + (item) => item!.conversationID == conv?.conversationID); + if(index > -1){ + conversation = _conversationList[index]!; + } + if(conversation == null){ + return Container(); + } final option1 = conv?.messageCount; return TIMUIKitSearchItem( onClick: () async { - onEnterConversation(conversation, keyword); + onEnterConversation(conversation!, keyword); }, faceUrl: conversation.faceUrl ?? "", showName: conversation.showName ?? "", diff --git a/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg_detail.dart b/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg_detail.dart index 3a9b0a8..622cf41 100644 --- a/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg_detail.dart +++ b/lib/ui/views/TIMUIKitSearch/tim_uikit_search_msg_detail.dart @@ -3,14 +3,16 @@ import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/time_ago.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_item.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_search_view_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_showAll.dart'; - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/tim_uikit_search_not_support.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; class TIMUIKitSearchMsgDetail extends StatefulWidget { /// Conversation need search @@ -19,6 +21,8 @@ class TIMUIKitSearchMsgDetail extends StatefulWidget { /// initial keyword final String keyword; + final List? initMessageList; + /// the callback after clicking each conversation message item final Function(V2TimConversation, V2TimMessage?) onTapConversation; @@ -29,7 +33,8 @@ class TIMUIKitSearchMsgDetail extends StatefulWidget { this.isAutoFocus = true, required this.currentConversation, required this.keyword, - required this.onTapConversation}) + required this.onTapConversation, + this.initMessageList}) : super(key: key); @override @@ -42,6 +47,8 @@ class TIMUIKitSearchMsgDetailState String keywordState = ""; int currentPage = 0; final FocusNode focusNode = FocusNode(); + final TextEditingController _controller = TextEditingController(); + final ScrollController _scrollController = ScrollController(); @override void initState() { @@ -54,7 +61,7 @@ class TIMUIKitSearchMsgDetailState final msgType = message.elemType; final isRevokedMessage = message.status == 6; if (isRevokedMessage) { - final isSelf = message.isSelf ?? false; + final isSelf = message.isSelf ?? true; final option2 = isSelf ? TIM_t("您") : message.nickName ?? message.sender; return TIM_t_para("{{option2}}撤回了一条消息", "$option2撤回了一条消息")( option2: option2); @@ -86,15 +93,12 @@ class TIMUIKitSearchMsgDetailState } List _renderListMessage( - List msgList, BuildContext context) { + List msgList, BuildContext context, bool isDesktopScreen) { List listWidget = []; listWidget = msgList.map((message) { return Container( padding: const EdgeInsets.fromLTRB(16, 0, 16, 0), - decoration: const BoxDecoration( - color: Colors.white, - ), child: TIMUIKitSearchItem( faceUrl: message.faceUrl ?? "", showName: TencentUtils.checkString(message.nickName) ?? @@ -105,6 +109,9 @@ class TIMUIKitSearchMsgDetailState TencentUtils.checkString(message.userID) ?? message.sender ?? "", + lineOneRight: (isDesktopScreen && message.timestamp != null) + ? TimeAgo().getTimeForMessage(message.timestamp!) + : null, lineTwo: _getMsgElem(message), onClick: () { focusNode.unfocus(); @@ -147,6 +154,7 @@ class TIMUIKitSearchMsgDetailState @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; if (PlatformUtils().isWeb) { return TIMUIKitSearchNotSupport(); } @@ -156,9 +164,19 @@ class TIMUIKitSearchMsgDetailState value: serviceLocator()) ], builder: (context, w) { - final List currentMsgListForConversation = + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + List currentMsgListForConversation = Provider.of(context) .currentMsgListForConversation; + final currentText = _controller.text; + if (currentMsgListForConversation.isEmpty && + widget.initMessageList != null && + widget.initMessageList!.isNotEmpty && currentText.isEmpty) { + currentMsgListForConversation = widget.initMessageList!; + } + final int totalMsgInConversationCount = Provider.of(context) .totalMsgInConversationCount; @@ -169,35 +187,66 @@ class TIMUIKitSearchMsgDetailState currentFocus.unfocus(); } }, - child: Scaffold( - body: Column( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + if (isDesktopScreen) + Container( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 0), + child: Row( + children: [ + SizedBox( + child: Avatar( + faceUrl: widget.currentConversation.faceUrl ?? "", + showName: ""), + width: 30, + height: 30, + ), + const SizedBox(width: 16), + Text( + widget.currentConversation.showName ?? + widget.currentConversation.userID ?? + "", + style: TextStyle( + fontSize: 16, + color: theme.darkTextColor, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), TIMUIKitSearchInput( focusNode: focusNode, + controller: _controller, isAutoFocus: widget.isAutoFocus, onChange: (String value) { updateMsgResult(value, true); }, initValue: widget.keyword, - prefixText: Text( - widget.currentConversation.showName ?? - widget.currentConversation.userID ?? - "", - maxLines: 1, - overflow: TextOverflow.ellipsis, + prefixIcon: Icon( + Icons.search, + size: 16, + color: hexToColor("979797"), ), ), Expanded( - child: ListView( - children: [ - ..._renderListMessage(currentMsgListForConversation, context), - _renderShowALl(keywordState.isNotEmpty && - totalMsgInConversationCount > - currentMsgListForConversation.length) - ], - )), + child: Scrollbar( + controller: _scrollController, + child: ListView( + controller: _scrollController, + children: [ + ..._renderListMessage( + currentMsgListForConversation, context, isDesktopScreen), + _renderShowALl(keywordState.isNotEmpty && + totalMsgInConversationCount > + currentMsgListForConversation.length) + ], + ), + )), ], - )), + ), ); }, ); diff --git a/lib/ui/widgets/avatar.dart b/lib/ui/widgets/avatar.dart index 888ffa2..25e5ac6 100644 --- a/lib/ui/widgets/avatar.dart +++ b/lib/ui/widgets/avatar.dart @@ -1,7 +1,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; -import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/image_screen.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart'; @@ -13,8 +13,8 @@ class Avatar extends TIMUIKitStatelessWidget { final String faceUrl; final String showName; final bool isFromLocalAsset; - final BorderRadius? borderRadius; final CoreServicesImpl coreService = serviceLocator(); + final BorderRadius? borderRadius; final V2TimUserStatus? onlineStatus; final int? type; // 1 c2c 2 group final bool isShowBigWhenClick; @@ -25,10 +25,10 @@ class Avatar extends TIMUIKitStatelessWidget { {Key? key, required this.faceUrl, this.onlineStatus, - this.borderRadius, - required this.showName, + required this.showName, this.isShowBigWhenClick = false, this.isFromLocalAsset = false, + this.borderRadius, this.type = 1}) : super(key: key); @@ -39,6 +39,7 @@ class Avatar extends TIMUIKitStatelessWidget { TencentUtils.checkString( selfInfoViewModel.globalConfig?.defaultAvatarAssetPath) ?? 'images/default_c2c_head.png', + fit: BoxFit.cover, package: selfInfoViewModel.globalConfig?.defaultAvatarAssetPath != null ? null @@ -48,6 +49,7 @@ class Avatar extends TIMUIKitStatelessWidget { TencentUtils.checkString( selfInfoViewModel.globalConfig?.defaultAvatarAssetPath) ?? 'images/default_group_head.png', + fit: BoxFit.cover, package: selfInfoViewModel.globalConfig?.defaultAvatarAssetPath != null ? null @@ -58,7 +60,10 @@ class Avatar extends TIMUIKitStatelessWidget { // final emptyAvatarBuilder = coreService.emptyAvatarBuilder; if (faceUrl != "") { if (isFromLocalAsset) { - return Image.asset(faceUrl); + return Image.asset( + faceUrl, + fit: BoxFit.cover, + ); } return CachedNetworkImage( imageUrl: faceUrl, @@ -79,6 +84,7 @@ class Avatar extends TIMUIKitStatelessWidget { TencentUtils.checkString(selfInfoViewModel .globalConfig?.defaultAvatarAssetPath) ?? 'images/default_c2c_head.png', + fit: BoxFit.cover, package: selfInfoViewModel.globalConfig?.defaultAvatarAssetPath != null @@ -90,6 +96,7 @@ class Avatar extends TIMUIKitStatelessWidget { TencentUtils.checkString(selfInfoViewModel .globalConfig?.defaultAvatarAssetPath) ?? 'images/default_group_head.png', + fit: BoxFit.cover, package: selfInfoViewModel.globalConfig?.defaultAvatarAssetPath != null @@ -133,14 +140,18 @@ class Avatar extends TIMUIKitStatelessWidget { child: Hero( tag: faceUrl, child: ClipRRect( - borderRadius: borderRadius ?? selfInfoViewModel.globalConfig?.defaultAvatarBorderRadius ?? BorderRadius.circular(4.8), + borderRadius: borderRadius ?? + selfInfoViewModel.globalConfig?.defaultAvatarBorderRadius ?? + BorderRadius.circular(4.8), child: getImageWidget(context, theme), ), ), ), if (!isShowBigWhenClick) ClipRRect( - borderRadius: borderRadius ?? selfInfoViewModel.globalConfig?.defaultAvatarBorderRadius ?? BorderRadius.circular(4.8), + borderRadius: borderRadius ?? + selfInfoViewModel.globalConfig?.defaultAvatarBorderRadius ?? + BorderRadius.circular(4.8), child: getImageWidget(context, theme), ), if (onlineStatus?.statusType != null && onlineStatus?.statusType != 0) diff --git a/lib/ui/widgets/az_list_view.dart b/lib/ui/widgets/az_list_view.dart index 95462eb..868a45a 100644 --- a/lib/ui/widgets/az_list_view.dart +++ b/lib/ui/widgets/az_list_view.dart @@ -1,10 +1,11 @@ -import 'package:azlistview/azlistview.dart'; +import 'package:azlistview_all_platforms/azlistview_all_platforms.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; class AZListViewContainer extends StatefulWidget { final List? memberList; @@ -74,36 +75,40 @@ class _AZListViewContainerState extends TIMUIKitState { @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return ChangeNotifierProvider.value( value: serviceLocator(), child: Consumer( - builder: (context, tuiTheme, child) => AzListView( - physics: const BouncingScrollPhysics( - parent: AlwaysScrollableScrollPhysics()), - data: _list!, - itemCount: _list!.length, - itemBuilder: widget.itemBuilder, - indexBarData: widget.isShowIndexBar - ? SuspensionUtil.getTagIndexList(_list!) - .where((element) => element != "@") - .toList() - : [], - susItemBuilder: (BuildContext context, int index) { - if (widget.susItemBuilder != null) { - return widget.susItemBuilder!(context, index); - } - ISuspensionBeanImpl model = _list![index]; - if (model.getSuspensionTag() == "@") { - return Container(); - } - return getSusItem(context, model.getSuspensionTag()); - }))); + builder: (context, tuiTheme, child) => Scrollbar( + child: AzListView( + physics: const BouncingScrollPhysics( + parent: AlwaysScrollableScrollPhysics()), + data: _list!, + itemCount: _list!.length, + itemBuilder: widget.itemBuilder, + indexBarData: (!isDesktopScreen && widget.isShowIndexBar) + ? SuspensionUtil.getTagIndexList(_list!) + .where((element) => element != "@") + .toList() + : [], + susItemBuilder: (BuildContext context, int index) { + if (widget.susItemBuilder != null) { + return widget.susItemBuilder!(context, index); + } + ISuspensionBeanImpl model = _list![index]; + if (model.getSuspensionTag() == "@") { + return Container(); + } + return getSusItem(context, model.getSuspensionTag()); + })))); } } class ISuspensionBeanImpl extends ISuspensionBean { String tagIndex; T memberInfo; + ISuspensionBeanImpl({required this.tagIndex, required this.memberInfo}); @override diff --git a/lib/ui/widgets/column_menu.dart b/lib/ui/widgets/column_menu.dart new file mode 100644 index 0000000..fdd8869 --- /dev/null +++ b/lib/ui/widgets/column_menu.dart @@ -0,0 +1,91 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; + +class ColumnMenuItem { + String label; + VoidCallback onClick; + Widget? icon; + + ColumnMenuItem({required this.label, required this.onClick, this.icon}); +} + +class TUIKitColumnMenu extends StatefulWidget { + const TUIKitColumnMenu({Key? key, required this.data, this.padding}) : super(key: key); + + final List data; + final EdgeInsetsGeometry? padding; + + @override + State createState() => TUIKitColumnMenuState(); +} + +class TUIKitColumnMenuState extends TIMUIKitState { + + List renderMenuItems(TUITheme theme) { + return widget.data + .map( + (item) => Material( + color: Colors.white, + child: InkWell( + onTap: () { + item.onClick(); + }, + child: Container( + padding: widget.padding ?? const EdgeInsets.all(10), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (item.icon != null) item.icon!, + if (item.icon != null) const SizedBox( + height: 4, + width: 6, + ), + Text( + item.label, + style: TextStyle( + decoration: TextDecoration.none, + color: theme.darkTextColor, + fontSize: 14, + ), + ) + ], + ), + ), + ), + ), + ) + .toList(); + } + + @override + Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final theme = value.theme; + return Container( + padding: const EdgeInsets.all(4), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: min(MediaQuery.of(context).size.width * 0.7, 350), + ), + child: Table( + columnWidths: const { + 0: IntrinsicColumnWidth(), + }, + children: [ + ...renderMenuItems(theme).map((e) => TableRow( + children: [ + e + ] + )) + ] + ), + ), + ); + } +} diff --git a/lib/ui/widgets/contact_list.dart b/lib/ui/widgets/contact_list.dart index eb3d18c..a5a9285 100644 --- a/lib/ui/widgets/contact_list.dart +++ b/lib/ui/widgets/contact_list.dart @@ -1,12 +1,13 @@ -import 'package:azlistview/azlistview.dart'; + +import 'package:azlistview_all_platforms/azlistview_all_platforms.dart'; import 'package:flutter/material.dart'; import 'package:lpinyin/lpinyin.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_friendship_view_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; - import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/az_list_view.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/radio_button.dart'; @@ -19,6 +20,7 @@ class ContactList extends StatefulWidget { final Function(List selectedMember)? onSelectedMemberItemChange; final Function()? handleSlidableDelte; + final Color? bgColor; /// tap联系人列表项回调 final void Function(V2TimFriendInfo item)? onTapItem; @@ -39,21 +41,25 @@ class ContactList extends StatefulWidget { /// the builder for the empty item, especially when there is no contact final Widget Function(BuildContext context)? emptyBuilder; - const ContactList( - {Key? key, - required this.contactList, - this.isCanSelectMemberItem = false, - this.onSelectedMemberItemChange, - this.isCanSlidableDelete = false, - this.handleSlidableDelte, - this.onTapItem, - this.topList, - this.topListItemBuilder, - this.isShowOnlineStatus = false, - this.maxSelectNum, - this.groupMemberList, - this.emptyBuilder}) - : super(key: key); + final String? currentItem; + + const ContactList({ + Key? key, + required this.contactList, + this.isCanSelectMemberItem = false, + this.onSelectedMemberItemChange, + this.isCanSlidableDelete = false, + this.handleSlidableDelte, + this.onTapItem, + this.bgColor, + this.topList, + this.topListItemBuilder, + this.isShowOnlineStatus = false, + this.maxSelectNum, + this.groupMemberList, + this.emptyBuilder, + this.currentItem, + }) : super(key: key); @override State createState() => _ContactListState(); @@ -116,6 +122,9 @@ class _ContactListState extends TIMUIKitState { -1) > -1; } + + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + return Container( padding: const EdgeInsets.only(top: 8, left: 16, right: 12), decoration: BoxDecoration( @@ -151,8 +160,8 @@ class _ContactListState extends TIMUIKitState { padding: const EdgeInsets.only(bottom: 12), margin: const EdgeInsets.only(right: 12), child: SizedBox( - height: 40, - width: 40, + height: isDesktopScreen ? 30 : 40, + width: isDesktopScreen ? 30 : 40, child: Avatar( onlineStatus: onlineStatus, faceUrl: faceUrl, @@ -165,7 +174,8 @@ class _ContactListState extends TIMUIKitState { padding: const EdgeInsets.only(top: 10, bottom: 20, right: 28), child: Text( showName, - style: const TextStyle(color: Colors.black, fontSize: 18), + style: TextStyle( + color: Colors.black, fontSize: isDesktopScreen ? 14 : 18), ), )), ], @@ -174,6 +184,7 @@ class _ContactListState extends TIMUIKitState { } Widget generateTopItem(memberInfo) { + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (widget.topListItemBuilder != null) { final customWidget = widget.topListItemBuilder!(memberInfo); if (customWidget != null) { @@ -193,8 +204,8 @@ class _ContactListState extends TIMUIKitState { child: Row( children: [ Container( - height: 40, - width: 40, + height: isDesktopScreen ? 30 : 40, + width: isDesktopScreen ? 30 : 40, margin: const EdgeInsets.only(right: 12, bottom: 12), child: memberInfo.icon, ), @@ -206,8 +217,9 @@ class _ContactListState extends TIMUIKitState { children: [ Text( memberInfo.name, - style: - TextStyle(color: hexToColor("111111"), fontSize: 18), + style: TextStyle( + color: hexToColor("111111"), + fontSize: isDesktopScreen ? 14 : 18), ), Expanded(child: Container()), // if (item.id == "newContact") @@ -232,6 +244,7 @@ class _ContactListState extends TIMUIKitState { final TUITheme theme = value.theme; final showList = _getShowList(widget.contactList); + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; if (widget.topList != null && widget.topList!.isNotEmpty) { final topList = widget.topList! @@ -259,28 +272,35 @@ class _ContactListState extends TIMUIKitState { if (memberInfo is TopListItem) { return generateTopItem(memberInfo); } else { - return InkWell( - onTap: () { - if (widget.isCanSelectMemberItem) { - if (selectedMember.contains(memberInfo)) { - selectedMember.remove(memberInfo); - } else { - if (selectedMemberIsOverFlow()) { - return; + return Material( + color: (isDesktopScreen) + ? (widget.currentItem == memberInfo.userProfile.userID + ? theme.conversationItemChooseBgColor + : widget.bgColor) + : null, + child: InkWell( + onTap: () { + if (widget.isCanSelectMemberItem) { + if (selectedMember.contains(memberInfo)) { + selectedMember.remove(memberInfo); + } else { + if (selectedMemberIsOverFlow()) { + return; + } + selectedMember.add(memberInfo); } - selectedMember.add(memberInfo); + if (widget.onSelectedMemberItemChange != null) { + widget.onSelectedMemberItemChange!(selectedMember); + } + setState(() {}); + return; } - if (widget.onSelectedMemberItemChange != null) { - widget.onSelectedMemberItemChange!(selectedMember); + if (widget.onTapItem != null) { + widget.onTapItem!(memberInfo); } - setState(() {}); - return; - } - if (widget.onTapItem != null) { - widget.onTapItem!(memberInfo); - } - }, - child: _buildItem(theme, memberInfo), + }, + child: _buildItem(theme, memberInfo), + ), ); } }, @@ -293,5 +313,6 @@ class TopListItem { final String id; final Widget? icon; final Function()? onTap; + TopListItem({required this.name, required this.id, this.icon, this.onTap}); } diff --git a/lib/ui/widgets/customize_ball_pulse_header.dart b/lib/ui/widgets/customize_ball_pulse_header.dart index 20f04c9..6d984ec 100644 --- a/lib/ui/widgets/customize_ball_pulse_header.dart +++ b/lib/ui/widgets/customize_ball_pulse_header.dart @@ -115,10 +115,6 @@ class BallPulseHeaderWidgetState extends TIMUIKitState { // 是否运行动画 bool _isAnimated = false; - @override - void initState() { - super.initState(); - } // 循环动画 void _loopAnimated() { diff --git a/lib/ui/widgets/drag_widget.dart b/lib/ui/widgets/drag_widget.dart new file mode 100644 index 0000000..9cf12d7 --- /dev/null +++ b/lib/ui/widgets/drag_widget.dart @@ -0,0 +1,97 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class TUIKitDragArea extends StatefulWidget { + final Widget child; + final Offset? initOffset; + final VoidCallback? closeFun; + final bool isAllowDrag; + final Color? backgroundColor; + + const TUIKitDragArea( + {Key? key, + required this.child, + this.initOffset, + this.closeFun, + this.isAllowDrag = false, this.backgroundColor}) + : super(key: key); + + @override + _DragAreaStateStateful createState() => _DragAreaStateStateful(); +} + +class _DragAreaStateStateful extends State { + late Offset position; + double prevScale = 1; + double scale = 1; + + @override + void initState() { + super.initState(); + position = widget.initOffset ?? const Offset(0, 200); + } + + void updateScale(double zoom) => setState(() => scale = prevScale * zoom); + + void commitScale() => setState(() => prevScale = scale); + + void updatePosition(Offset newPosition) { + final maxY = MediaQuery.of(context).size.height - 100; + final maxX = MediaQuery.of(context).size.width - 100; + + final rebuildPosition = Offset( + max(0, min(newPosition.dx, maxX)), max(0, min(newPosition.dy, maxY))); + position = rebuildPosition; + } + + @override + Widget build(BuildContext context) { + return Container( + color: widget.backgroundColor, + child: Stack( + children: [ + Row( + children: [ + Expanded( + child: Column( + children: [ + Expanded( + child: GestureDetector( + onTap: () { + if (widget.closeFun != null) { + widget.closeFun!(); + } + }, + child: Container( + color: Colors.transparent, + ), + ) + ) + ], + )) + ], + ), + if (widget.isAllowDrag) + Positioned( + left: position.dx, + top: position.dy, + child: Draggable( + maxSimultaneousDrags: 1, + feedback: widget.child, + childWhenDragging: Container(), + onDragEnd: (details) => updatePosition(details.offset), + child: widget.child, + ), + ), + if (!widget.isAllowDrag) + Positioned( + left: position.dx, + top: position.dy, + child: widget.child, + ) + ], + ), + ); + } +} diff --git a/lib/ui/widgets/emoji.dart b/lib/ui/widgets/emoji.dart index 4333474..f7ec647 100644 --- a/lib/ui/widgets/emoji.dart +++ b/lib/ui/widgets/emoji.dart @@ -1,22 +1,21 @@ -import 'package:json_annotation/json_annotation.dart'; -part 'emoji.g.dart'; - -@JsonSerializable() -class Emoji extends Object { - @JsonKey(name: 'name') +class Emoji { String name; - - @JsonKey(name: 'unicode') int unicode; - Emoji( - this.name, - this.unicode, - ); + Emoji({required this.name, required this.unicode}); - factory Emoji.fromJson(Map srcJson) => - _$EmojiFromJson(srcJson); + factory Emoji.fromJson(Map json) { + return Emoji( + name: json['name'], + unicode: json['unicode'], + ); + } - Map toJson() => _$EmojiToJson(this); -} + Map toJson() { + final Map data = {}; + data['name'] = name; + data['unicode'] = unicode; + return data; + } +} \ No newline at end of file diff --git a/lib/ui/widgets/emoji.g.dart b/lib/ui/widgets/emoji.g.dart deleted file mode 100644 index 02519f5..0000000 --- a/lib/ui/widgets/emoji.g.dart +++ /dev/null @@ -1,19 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'emoji.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Emoji _$EmojiFromJson(Map json) { - return Emoji( - json['name'] as String, - json['unicode'] as int, - ); -} - -Map _$EmojiToJson(Emoji instance) => { - 'name': instance.name, - 'unicode': instance.unicode, - }; diff --git a/lib/ui/widgets/forward_message_screen.dart b/lib/ui/widgets/forward_message_screen.dart index d8b791d..781fb15 100644 --- a/lib/ui/widgets/forward_message_screen.dart +++ b/lib/ui/widgets/forward_message_screen.dart @@ -7,20 +7,24 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/recent_conversation_list.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; +GlobalKey<_ForwardMessageScreenState> forwardMessageScreenKey = GlobalKey(); + class ForwardMessageScreen extends StatefulWidget { final bool isMergerForward; final ConvType conversationType; final TUIChatSeparateViewModel model; + final VoidCallback? onClose; const ForwardMessageScreen( {Key? key, this.isMergerForward = false, required this.conversationType, - required this.model}) + required this.model, this.onClose}) : super(key: key); @override @@ -56,7 +60,7 @@ class _ForwardMessageScreenState extends TIMUIKitState { }).toList(); } - _handleForwardMessage() async { + handleForwardMessage() async { if (widget.isMergerForward) { await widget.model.sendMergerMessage( conversationList: _conversationList, @@ -69,30 +73,44 @@ class _ForwardMessageScreenState extends TIMUIKitState { .sendForwardMessage(conversationList: _conversationList); } widget.model.updateMultiSelectStatus(false); - Navigator.pop(context); + + if(widget.onClose != null){ + widget.onClose!(); + }else{ + Navigator.pop(context); + } } @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; final TUITheme theme = value.theme; + if(isDesktopScreen){ + isMultiSelect = true; + return RecentForwardList( + isMultiSelect: isMultiSelect, + onChanged: (conversationList) { + _conversationList = conversationList; + + if (!isMultiSelect) { + handleForwardMessage(); + } + }, + ); + } return Scaffold( appBar: AppBar( title: Text( TIM_t("选择"), - style: const TextStyle( - color: Colors.white, + style: TextStyle( + color: theme.appbarTextColor, fontSize: 17, ), ), shadowColor: theme.weakBackgroundColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, leading: TextButton( onPressed: () { if (isMultiSelect) { @@ -102,17 +120,22 @@ class _ForwardMessageScreenState extends TIMUIKitState { }); } else { widget.model.updateMultiSelectStatus(false); - Navigator.pop(context); + if(widget.onClose != null){ + widget.onClose!(); + }else{ + Navigator.pop(context); + } } }, child: Text( TIM_t("取消"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 14, ), ), ), + leadingWidth: 80, actions: [ TextButton( onPressed: () { @@ -121,7 +144,7 @@ class _ForwardMessageScreenState extends TIMUIKitState { isMultiSelect = true; }); } else { - _handleForwardMessage(); + handleForwardMessage(); } }, child: Text( @@ -140,7 +163,7 @@ class _ForwardMessageScreenState extends TIMUIKitState { _conversationList = conversationList; if (!isMultiSelect) { - _handleForwardMessage(); + handleForwardMessage(); } }, ), diff --git a/lib/ui/widgets/group_member_list.dart b/lib/ui/widgets/group_member_list.dart index 9972d16..464763c 100644 --- a/lib/ui/widgets/group_member_list.dart +++ b/lib/ui/widgets/group_member_list.dart @@ -1,10 +1,11 @@ // ignore_for_file: must_be_immutable -import 'package:azlistview/azlistview.dart'; +import 'package:azlistview_all_platforms/azlistview_all_platforms.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slidable_for_tencent_im/flutter_slidable.dart'; import 'package:lpinyin/lpinyin.dart'; import 'package:provider/provider.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/optimize_utils.dart'; @@ -25,7 +26,7 @@ class GroupProfileMemberList extends StatefulWidget { final Function(List selectedMember)? onSelectedMemberChange; // notice: onTapMemberItem and onSelectedMemberChange use together will triger together - final Function(V2TimGroupMemberFullInfo memberInfo)? onTapMemberItem; + final Function(V2TimGroupMemberFullInfo memberInfo, TapDownDetails? tapDetails)? onTapMemberItem; // When sliding to the bottom bar callBack final Function()? touchBottomCallBack; @@ -111,6 +112,8 @@ class _GroupProfileMemberListState Widget _buildListItem( BuildContext context, V2TimGroupMemberFullInfo memberInfo) { final theme = Provider.of(context).theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop; final isGroupMember = memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_MEMBER; return Container( @@ -142,12 +145,12 @@ class _GroupProfileMemberListState margin: const EdgeInsets.only(right: 10), child: CheckBoxButton( onChanged: (isChecked) { - if (widget.maxSelectNum != null && - selectedMember.length >= - widget.maxSelectNum!) { - return; - } if (isChecked) { + if (widget.maxSelectNum != null && + selectedMember.length >= + widget.maxSelectNum!) { + return; + } selectedMember.add(memberInfo); } else { selectedMember.remove(memberInfo); @@ -160,8 +163,8 @@ class _GroupProfileMemberListState isChecked: selectedMember.contains(memberInfo)), ), Container( - width: 36, - height: 36, + width: isDesktopScreen ? 30 : 36, + height: isDesktopScreen ? 30 : 36, margin: const EdgeInsets.only(right: 10), child: Avatar( faceUrl: memberInfo.faceUrl ?? "", @@ -170,7 +173,7 @@ class _GroupProfileMemberListState ), ), Text(_getShowName(memberInfo), - style: const TextStyle(fontSize: 16)), + style: TextStyle(fontSize: isDesktopScreen ? 14 : 16)), memberInfo.role == GroupMemberRoleType.V2TIM_GROUP_MEMBER_ROLE_OWNER ? Container( @@ -178,7 +181,7 @@ class _GroupProfileMemberListState child: Text(TIM_t("群主"), style: TextStyle( color: theme.ownerColor, - fontSize: 12, + fontSize: isDesktopScreen ? 10 :12, )), padding: const EdgeInsets.fromLTRB(5, 0, 5, 0), decoration: BoxDecoration( @@ -215,17 +218,17 @@ class _GroupProfileMemberListState ), onTap: () { if (widget.onTapMemberItem != null) { - widget.onTapMemberItem!(memberInfo); + widget.onTapMemberItem!(memberInfo, null); } if (widget.canSelectMember) { - if (widget.maxSelectNum != null && - selectedMember.length >= widget.maxSelectNum!) { - return; - } final isChecked = selectedMember.contains(memberInfo); if (isChecked) { selectedMember.remove(memberInfo); } else { + if (widget.maxSelectNum != null && + selectedMember.length >= widget.maxSelectNum!) { + return; + } selectedMember.add(memberInfo); } if (widget.onSelectedMemberChange != null) { @@ -270,6 +273,9 @@ class _GroupProfileMemberListState Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor() == DeviceType.Desktop; + final throteFunction = OptimizeUtils.throttle((ScrollNotification notification) { final pixels = notification.metrics.pixels; @@ -283,7 +289,7 @@ class _GroupProfileMemberListState }, 300); final showList = _getShowList(widget.memberList); return Container( - color: theme.weakBackgroundColor, + color: isDesktopScreen ? null : theme.weakBackgroundColor, child: SafeArea( child: Column( children: [ @@ -298,19 +304,22 @@ class _GroupProfileMemberListState ? Center( child: Text(TIM_t("暂无群成员")), ) - : AZListViewContainer( - memberList: showList, - susItemBuilder: (context, index) { - final model = showList[index]; - return getSusItem( - context, theme, model.getSuspensionTag()); - }, - itemBuilder: (context, index) { - final memberInfo = showList[index].memberInfo - as V2TimGroupMemberFullInfo; + : Container( + padding: isDesktopScreen ? const EdgeInsets.symmetric( horizontal: 16) : null, + child: AZListViewContainer( + memberList: showList, + susItemBuilder: (context, index) { + final model = showList[index]; + return getSusItem( + context, theme, model.getSuspensionTag()); + }, + itemBuilder: (context, index) { + final memberInfo = showList[index].memberInfo + as V2TimGroupMemberFullInfo; - return _buildListItem(context, memberInfo); - }), + return _buildListItem(context, memberInfo); + }), + ), )) ], )), diff --git a/lib/ui/widgets/link_preview/common/utils.dart b/lib/ui/widgets/link_preview/common/utils.dart index f14ea36..f720e18 100644 --- a/lib/ui/widgets/link_preview/common/utils.dart +++ b/lib/ui/widgets/link_preview/common/utils.dart @@ -1,15 +1,14 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:link_preview_generator/link_preview_generator.dart'; -import 'package:tencent_im_base/tencent_im_base.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/common/extensions.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/link_preview_entry.dart'; -import 'package:tencent_cloud_chat_uikit/ui/widgets/link_preview/models/link_preview_content.dart'; import 'package:url_launcher/url_launcher.dart'; class LinkUtils { static RegExp urlReg = RegExp( - r"(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]"); + r"([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/|[wW]{3}.|[wW][aA][pP].|[fF][tT][pP].|[fF][iI][lL][eE].)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]"); /// Get all the URL from a text message static List getURLMatches(String textMessage) { @@ -49,7 +48,7 @@ class LinkUtils { List urlMatches) async { // Request for preview information for all URL links synchronously final List urlPreview = - await Future.wait(urlMatches.map((e) async { + await Future.wait(urlMatches.map((e) async { String url = e; if (!e.contains("http")) { url = 'http://$e'; @@ -68,7 +67,7 @@ class LinkUtils { /// save the link info to local and call updating the message on UI, only works with [onUpdateMessage] static Future saveToLocalAndUpdate(V2TimMessage message, - LocalCustomDataModel previewItem, VoidCallback onUpdateMessage) async { + LocalCustomDataModel previewItem, ValueChanged onUpdateMessage) async { if (message.msgID != null) { String saveInfo = LinkPreviewEntry.linkInfoToString(previewItem); final currentInfo = message.localCustomData; @@ -80,10 +79,13 @@ class LinkUtils { data['description'] = previewItem.description; saveInfo = json.encode(data); } - final result = await TencentImSDKPlugin.v2TIMManager.v2TIMMessageManager - .setLocalCustomData(msgID: message.msgID!, localCustomData: saveInfo); - if (result.code == 0) { - onUpdateMessage(); + message.localCustomData = saveInfo; + if(saveInfo != currentInfo){ + final result = await TencentImSDKPlugin.v2TIMManager.v2TIMMessageManager + .setLocalCustomData(msgID: message.msgID!, localCustomData: saveInfo); + if (result.code == 0) { + onUpdateMessage(message); + } } } } diff --git a/lib/ui/widgets/link_preview/link_preview_entry.dart b/lib/ui/widgets/link_preview/link_preview_entry.dart index 9dc355f..1d42689 100644 --- a/lib/ui/widgets/link_preview/link_preview_entry.dart +++ b/lib/ui/widgets/link_preview/link_preview_entry.dart @@ -8,21 +8,17 @@ import 'models/link_preview_content.dart'; class LinkPreviewEntry { /// get the text message with hyperlinks - static LinkPreviewText? getHyperlinksText( - String messageText, bool isMarkdown, - [Function(String)? onLinkTap, + static LinkPreviewText? getHyperlinksText(String messageText, bool isMarkdown, + {Function(String)? onLinkTap, + bool? isEnableTextSelection, bool isUseDefaultEmoji = false, - List customEmojiStickerList = const []]) { - - if (messageText == null) { - return null; - } - + List customEmojiStickerList = const []}) { return ({TextStyle? style}) { return isMarkdown ? LinkTextMarkdown( messageText: messageText, style: style, onLinkTap: onLinkTap) : LinkText( + isEnableTextSelection: isEnableTextSelection, messageText: messageText, style: style, onLinkTap: onLinkTap, @@ -34,7 +30,8 @@ class LinkPreviewEntry { /// get the [LinkPreviewContent] with preview widget and website information for the first link. /// If you provide `onUpdateMessage(String linkInfoJson)`, it can save the link info to local custom data than call updating the message on UI automatically. static Future getFirstLinkPreviewContent( - {required V2TimMessage message, VoidCallback? onUpdateMessage}) async { + {required V2TimMessage message, + ValueChanged? onUpdateMessage}) async { final String? messageText = message.textElem?.text; if (messageText == null) { return null; @@ -93,22 +90,4 @@ class LinkPreviewEntry { static String linkInfoToString(LocalCustomDataModel linkInfo) { return linkInfo.toString(); } - - // static LinkPreviewModel? linkInfoFromString(String linkInfoString){ - // final Map data = json.decode(linkInfoString); - // LinkPreviewModel linkPreview = LinkPreviewModel( - // url: data['url'], - // image: data['image'], - // title: data['title'], - // description: data['description'] - // ); - // return isLinkInfoEmpty(linkPreview) ? null : linkPreview; - // } - // - // static bool isLinkInfoEmpty(LinkPreviewModel linkInfo){ - // if(linkInfo.image == null && linkInfo.title == null && linkInfo.description == null){ - // return true; - // } - // return false; - // } } diff --git a/lib/ui/widgets/link_preview/widgets/link_text.dart b/lib/ui/widgets/link_preview/widgets/link_text.dart index 0d304fe..a039b46 100644 --- a/lib/ui/widgets/link_preview/widgets/link_text.dart +++ b/lib/ui/widgets/link_preview/widgets/link_text.dart @@ -1,4 +1,7 @@ +// ignore_for_file: deprecated_member_use + import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_extended_text/extended_text.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -60,10 +63,13 @@ class LinkText extends TIMStatelessWidget { final List customEmojiStickerList; + final bool? isEnableTextSelection; + const LinkText( {Key? key, required this.messageText, this.onLinkTap, + this.isEnableTextSelection, this.style, this.isUseDefaultEmoji = false, this.customEmojiStickerList = const []}) @@ -124,6 +130,8 @@ class LinkText extends TIMStatelessWidget { @override Widget timBuild(BuildContext context) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return // Text.rich( // TextSpan(children: [..._getContentSpan(messageText, context)]), @@ -140,6 +148,9 @@ class LinkText extends TIMStatelessWidget { } } }, + selectionEnabled: isEnableTextSelection != null + ? isEnableTextSelection! + : isDesktopScreen, style: style ?? const TextStyle(fontSize: 16.0), specialTextSpanBuilder: DefaultSpecialTextSpanBuilder( isUseDefaultEmoji: isUseDefaultEmoji, diff --git a/lib/ui/widgets/merger_message_screen.dart b/lib/ui/widgets/merger_message_screen.dart index 54cccba..d086f10 100644 --- a/lib/ui/widgets/merger_message_screen.dart +++ b/lib/ui/widgets/merger_message_screen.dart @@ -4,6 +4,8 @@ import 'package:flutter/material.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/common_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; @@ -56,8 +58,10 @@ class MergerMessageScreenState extends TIMUIKitState { message.cloudCustomData != null && message.cloudCustomData != ""; if (hasCustomData) { try { - final CloudCustomData messageCloudCustomData = - CloudCustomData.fromJson(json.decode(message.cloudCustomData!)); + final CloudCustomData messageCloudCustomData = CloudCustomData.fromJson(json.decode( + TencentUtils.checkString(message.cloudCustomData) != null + ? message.cloudCustomData! + : "{}")); if (messageCloudCustomData.messageReply != null) { MessageRepliedData.fromJson(messageCloudCustomData.messageReply!); return true; @@ -72,7 +76,7 @@ class MergerMessageScreenState extends TIMUIKitState { Widget _getMsgItem(V2TimMessage message) { final type = message.elemType; - final isFromSelf = message.isSelf ?? false; + final isFromSelf = message.isSelf ?? true; switch (type) { case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM: @@ -126,8 +130,8 @@ class MergerMessageScreenState extends TIMUIKitState { return TIMUIKitTextElem( chatModel: widget.model, message: message, - isFromSelf: message.isSelf ?? false, - clearJump: (){}, + isFromSelf: message.isSelf ?? true, + clearJump: () {}, isShowJump: false, isShowMessageReaction: false, ); @@ -229,7 +233,7 @@ class MergerMessageScreenState extends TIMUIKitState { final showName = message.nickName ?? message.userID ?? ""; final theme = Provider.of(context).theme; return Container( - margin: const EdgeInsets.only(bottom: 20), + margin: const EdgeInsets.only(top: 20), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -264,25 +268,11 @@ class MergerMessageScreenState extends TIMUIKitState { Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - return Scaffold( - appBar: AppBar( - title: Text( - TIM_t("聊天记录"), - style: const TextStyle(color: Colors.white, fontSize: 17), - ), - shadowColor: theme.weakDividerColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, - )), - body: messageList.isEmpty + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + Widget messageListPage() { + return messageList.isEmpty ? Row( children: [ Expanded( @@ -301,8 +291,8 @@ class MergerMessageScreenState extends TIMUIKitState { )) ], ) - : Padding( - padding: const EdgeInsets.all(16), + : Container( + padding: isDesktopScreen ? null : const EdgeInsets.all(16), child: ListView.builder( shrinkWrap: true, itemCount: messageList.length, @@ -311,7 +301,27 @@ class MergerMessageScreenState extends TIMUIKitState { return _itemBuilder(message, context); }, ), - ), - ); + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: messageListPage(), + ), + defaultWidget: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("聊天记录"), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), + ), + shadowColor: theme.weakDividerColor, + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + )), + body: messageListPage(), + )); } } diff --git a/lib/ui/widgets/message_read_receipt.dart b/lib/ui/widgets/message_read_receipt.dart index f2f9bbf..473ebff 100644 --- a/lib/ui/widgets/message_read_receipt.dart +++ b/lib/ui/widgets/message_read_receipt.dart @@ -3,10 +3,10 @@ import 'package:flutter/material.dart'; // ignore: unused_import import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/separate_models/tui_chat_separate_view_model.dart'; - import 'package:tencent_cloud_chat_uikit/ui/utils/message.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/time_ago.dart'; @@ -23,7 +23,7 @@ class MessageReadReceipt extends StatefulWidget { final V2TimMessage messageItem; final int unreadCount; final int readCount; - final void Function(String userID)? onTapAvatar; + final void Function(String userID, TapDownDetails tapDetails)? onTapAvatar; final TUIChatSeparateViewModel model; const MessageReadReceipt( @@ -92,7 +92,7 @@ class _MessageReadReceiptState extends TIMUIKitState { Widget _getMsgItem(V2TimMessage message) { final type = message.elemType; - final isFromSelf = message.isSelf ?? false; + final isFromSelf = message.isSelf ?? true; switch (type) { case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM: @@ -170,10 +170,13 @@ class _MessageReadReceiptState extends TIMUIKitState { Widget _memberItemBuilder(V2TimGroupMemberInfo item, TUITheme theme) { final faceUrl = item.faceUrl ?? ''; final showName = _getShowName(item); + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + return InkWell( - onTap: () { + onTapDown: (details) { if (widget.onTapAvatar != null) { - widget.onTapAvatar!(item.userID!); + widget.onTapAvatar!(item.userID!, details); } }, child: Container( @@ -181,15 +184,15 @@ class _MessageReadReceiptState extends TIMUIKitState { child: Row( children: [ Container( - height: 40, - width: 40, - margin: const EdgeInsets.only(right: 12), + height: isDesktopScreen ? 30 : 40, + width: isDesktopScreen ? 30 : 40, + margin: EdgeInsets.only(right: 12, bottom: isDesktopScreen ? 6 : 0), child: Avatar(faceUrl: faceUrl, showName: showName), ), Expanded( child: Container( alignment: Alignment.centerLeft, - padding: const EdgeInsets.only(top: 10, bottom: 19, right: 28), + padding: EdgeInsets.only(top: 10, bottom: isDesktopScreen ? 14 : 19, right: 28), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -197,7 +200,7 @@ class _MessageReadReceiptState extends TIMUIKitState { CommonColor.weakDividerColor))), child: Text( showName, - style: const TextStyle(color: Colors.black, fontSize: 18), + style: TextStyle(color: Colors.black, fontSize: isDesktopScreen ? 14 : 18), ), )), ], @@ -211,170 +214,170 @@ class _MessageReadReceiptState extends TIMUIKitState { final TUITheme theme = value.theme; final option1 = widget.readCount; final option2 = widget.unreadCount; - return DefaultTabController( - length: 2, - child: Scaffold( - appBar: AppBar( - title: Text( - TIM_t("消息详情"), - style: const TextStyle(color: Colors.white, fontSize: 17), - ), - shadowColor: theme.weakDividerColor, - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - iconTheme: const IconThemeData( - color: Colors.white, - )), - body: Container( - color: Colors.white, - child: Column( - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 16, horizontal: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Text(MessageUtils.getDisplayName(widget.messageItem)), - const SizedBox( - width: 8, - ), - Text( - TimeAgo().getTimeForMessage( - widget.messageItem.timestamp ?? 0), - softWrap: true, - style: TextStyle( - fontSize: 12, color: theme.weakTextColor), - ) - ], - ), - const SizedBox( - height: 6, - ), - _getMsgItem(widget.messageItem) - ], - ), - ), - Container( - height: 8, - color: theme.weakBackgroundColor, - ), - Row( - // direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - currentIndex = 0; - setState(() {}); - }, - child: Container( - height: 50.0, - alignment: Alignment.bottomCenter, - padding: const EdgeInsets.only(bottom: 12), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - width: 2, - color: currentIndex == 0 - ? theme.primaryColor! - : Colors.white))), - child: Text( - TIM_t_para("{{option1}}人已读", "$option1人已读")( - option1: option1), - style: TextStyle( - color: currentIndex != 0 - ? theme.weakTextColor - : Colors.black, - fontSize: 18, - ), - ), - ), - ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () { - currentIndex = 1; - setState(() {}); - }, - child: Container( - alignment: Alignment.bottomCenter, - height: 50.0, - padding: const EdgeInsets.only(bottom: 12), - decoration: BoxDecoration( - color: Colors.white, - border: Border( - bottom: BorderSide( - width: 2, - color: currentIndex == 1 - ? theme.primaryColor! - : Colors.white))), - child: Text( - TIM_t_para("{{option2}}人未读", "$option2人未读")( - option2: option2), - style: TextStyle( - color: currentIndex != 1 - ? theme.weakTextColor - : Colors.black, - fontSize: 18, - ), - ), - ), - ), - ), - ], - ), - Container( - height: 1, - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: theme.weakDividerColor ?? - CommonColor.weakDividerColor))), - ), - Expanded( - child: IndexedStack( - index: currentIndex, + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + + Widget pageBody() { + return Container( + color: isDesktopScreen ? null : Colors.white, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - ListView.builder( - shrinkWrap: true, - itemCount: readMemberList.length, - itemBuilder: (context, index) { - if (!readMemberIsFinished && - index == readMemberList.length - 5) { - _getReadMemberList(); - } - return _memberItemBuilder(readMemberList[index], theme); - }), - ListView.builder( - shrinkWrap: true, - itemCount: unreadMemberList.length, - itemBuilder: (context, index) { - if (!unreadMemberIsFinished && - index == unreadMemberList.length - 5) { - _getUnreadMemberList(); - } - return _memberItemBuilder( - unreadMemberList[index], theme); - }), + Row( + children: [ + Text(MessageUtils.getDisplayName(widget.messageItem)), + const SizedBox( + width: 8, + ), + Text( + TimeAgo().getTimeForMessage( + widget.messageItem.timestamp ?? 0), + softWrap: true, + style: + TextStyle(fontSize: 12, color: theme.weakTextColor), + ) + ], + ), + const SizedBox( + height: 6, + ), + _getMsgItem(widget.messageItem) ], - )), - ], - ), + ), + ), + Container( + height: 8, + color: theme.weakBackgroundColor, + ), + Row( + // direction: Axis.horizontal, + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + currentIndex = 0; + setState(() {}); + }, + child: Container( + height: isDesktopScreen ? 40 : 50.0, + alignment: Alignment.bottomCenter, + padding: EdgeInsets.only(bottom: isDesktopScreen ? 8 : 12), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + width: 2, + color: currentIndex == 0 + ? theme.primaryColor! + : Colors.white))), + child: Text( + TIM_t_para("{{option1}}人已读", "$option1人已读")( + option1: option1), + style: TextStyle( + color: currentIndex != 0 + ? theme.weakTextColor + : Colors.black, + fontSize: isDesktopScreen ? 14 : 18, + ), + ), + ), + ), + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () { + currentIndex = 1; + setState(() {}); + }, + child: Container( + alignment: Alignment.bottomCenter, + height: isDesktopScreen ? 40 : 50.0, + padding: EdgeInsets.only(bottom: isDesktopScreen ? 8 : 12), + decoration: BoxDecoration( + color: Colors.white, + border: Border( + bottom: BorderSide( + width: 2, + color: currentIndex == 1 + ? theme.primaryColor! + : Colors.white))), + child: Text( + TIM_t_para("{{option2}}人未读", "$option2人未读")( + option2: option2), + style: TextStyle( + color: currentIndex != 1 + ? theme.weakTextColor + : Colors.black, + fontSize: isDesktopScreen ? 14 : 18, + ), + ), + ), + ), + ), + ], + ), + Container( + height: 1, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: theme.weakDividerColor ?? + CommonColor.weakDividerColor))), + ), + Expanded( + child: IndexedStack( + index: currentIndex, + children: [ + ListView.builder( + shrinkWrap: true, + itemCount: readMemberList.length, + itemBuilder: (context, index) { + if (!readMemberIsFinished && + index == readMemberList.length - 5) { + _getReadMemberList(); + } + return _memberItemBuilder(readMemberList[index], theme); + }), + ListView.builder( + shrinkWrap: true, + itemCount: unreadMemberList.length, + itemBuilder: (context, index) { + if (!unreadMemberIsFinished && + index == unreadMemberList.length - 5) { + _getUnreadMemberList(); + } + return _memberItemBuilder(unreadMemberList[index], theme); + }), + ], + )), + ], ), - ), - ); + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + desktopWidget: pageBody(), + defaultWidget: DefaultTabController( + length: 2, + child: Scaffold( + appBar: AppBar( + title: Text( + TIM_t("消息详情"), + style: TextStyle(color: theme.appbarTextColor, fontSize: 17), + ), + shadowColor: theme.weakDividerColor, + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + )), + body: pageBody()), + )); } } diff --git a/lib/ui/widgets/recent_conversation_list.dart b/lib/ui/widgets/recent_conversation_list.dart index 15c5d71..ac1c707 100644 --- a/lib/ui/widgets/recent_conversation_list.dart +++ b/lib/ui/widgets/recent_conversation_list.dart @@ -3,6 +3,7 @@ import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_conversation_view_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/az_list_view.dart'; @@ -42,6 +43,9 @@ class _RecentForwardListState extends TIMUIKitState { } Widget _buildItem(V2TimConversation conversation) { + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + final faceUrl = conversation.faceUrl ?? ""; final showName = conversation.showName ?? ""; @@ -49,8 +53,8 @@ class _RecentForwardListState extends TIMUIKitState { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (widget.isMultiSelect) - Padding( - padding: const EdgeInsets.only(left: 16.0), + Container( + padding: EdgeInsets.only(left: isDesktopScreen ? 8 : 16.0, top: isDesktopScreen ? 10 : 0), child: CheckBoxButton( isChecked: _selectedConversation.contains(conversation), onChanged: (value) { @@ -91,8 +95,8 @@ class _RecentForwardListState extends TIMUIKitState { child: Row( children: [ Container( - height: 40, - width: 40, + height: isDesktopScreen ? 30 : 40, + width: isDesktopScreen ? 30 : 40, margin: const EdgeInsets.only(right: 12), child: Avatar( faceUrl: faceUrl, @@ -103,15 +107,15 @@ class _RecentForwardListState extends TIMUIKitState { Expanded( child: Container( alignment: Alignment.centerLeft, - padding: const EdgeInsets.only(top: 10, bottom: 19), - decoration: const BoxDecoration( + padding: EdgeInsets.only(top: 10, bottom: isDesktopScreen ? 12 : 19), + decoration: isDesktopScreen ? null : const BoxDecoration( border: Border(bottom: BorderSide(color: Color(0xFFDBDBDB)))), child: Text( showName, // textAlign: TextAlign.center, style: - const TextStyle(color: Color(0xFF111111), fontSize: 18), + TextStyle(color: const Color(0xFF111111), fontSize: isDesktopScreen ? 16 : 18), ), )) ], @@ -122,10 +126,6 @@ class _RecentForwardListState extends TIMUIKitState { ); } - @override - void initState() { - super.initState(); - } @override void dispose() { @@ -147,12 +147,14 @@ class _RecentForwardListState extends TIMUIKitState { final recentConvList = serviceLocator().conversationList; final showList = _buildMemberList(recentConvList); + final isDesktopScreen = + TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; return AZListViewContainer( memberList: showList, isShowIndexBar: false, susItemBuilder: (context, index) { - return Container( + return isDesktopScreen ? Container() : Container( height: 40, width: MediaQuery.of(context).size.width, padding: const EdgeInsets.only(left: 16.0), diff --git a/lib/ui/widgets/textSize.dart b/lib/ui/widgets/textSize.dart index 8a32090..6f49560 100644 --- a/lib/ui/widgets/textSize.dart +++ b/lib/ui/widgets/textSize.dart @@ -1,3 +1,4 @@ + // ignore_for_file: file_names import 'package:flutter/material.dart'; @@ -60,16 +61,12 @@ class CustomText extends StatefulWidget { class _ExtendTextState extends State { String? text; - countTextSize() { TextStyle style = widget.style ?? const TextStyle(fontSize: 14); double textwidth = TextSize.boundingTextSize(widget.text, style).width; int offset = widget.offset ?? 3; if (textwidth > widget.width) { int position = widget.text.lastIndexOf('.'); - if(position < 0){ - position = widget.text.length; - } String overflowtext = widget.overflowtext ?? '...'; int overflowtextLength = overflowtext.length; double singTextSize = textwidth / widget.text.length; diff --git a/lib/ui/widgets/text_input_bottom_sheet.dart b/lib/ui/widgets/text_input_bottom_sheet.dart index 6389d76..76f9b0e 100644 --- a/lib/ui/widgets/text_input_bottom_sheet.dart +++ b/lib/ui/widgets/text_input_bottom_sheet.dart @@ -1,74 +1,247 @@ import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/drag_widget.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; class TextInputBottomSheet { - static showTextInputBottomSheet(BuildContext context, String title, - String tips, Function(String text) onSubmitted, TUITheme theme) { - TextEditingController _selectionController = TextEditingController(); + static OverlayEntry? entry; - showModalBottomSheet( - isScrollControlled: true, // !important - context: context, - builder: (BuildContext context) { - return SingleChildScrollView( - child: Container( - padding: EdgeInsets.only( - top: 16, - left: 16, - right: 16, - bottom: MediaQuery.of(context).viewInsets.bottom + 30, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, + static Widget inputBoxContent( + {required BuildContext context, + required String title, + String? tips, + required Function(String text) onSubmitted, + required TUITheme theme, + bool isShowCancel = false, + Offset? initOffset, + String? initText, + required TextEditingController selectionController}) { + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + selectionController.text = initText ?? ""; + return SingleChildScrollView( + child: Container( + padding: EdgeInsets.only( + top: 16, + left: 16, + right: 16, + bottom: + isDesktopScreen ? 16 : MediaQuery.of(context).viewInsets.bottom + 30, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 16), + child: Text(title, + style: + const TextStyle(fontWeight: FontWeight.w500, fontSize: 16)), + ), + Divider(height: 2, color: theme.weakDividerColor), + TextField( + + onSubmitted: (text) { + onSubmitted(text); + if (entry != null) { + entry?.remove(); + entry = null; + } else { + Navigator.pop(context); + } + }, + autofocus: true, + controller: selectionController, + ), + if(tips != null) Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.symmetric(vertical: 5), + height: 40, + child: Text( + tips, + style: const TextStyle(color: Colors.grey, fontSize: 12), + ), + ) + ], + ), + if (isDesktopScreen) + Row( + mainAxisAlignment: MainAxisAlignment.end, children: [ - Padding( - padding: const EdgeInsets.only(bottom: 16), - child: Text(title, - style: const TextStyle( - fontWeight: FontWeight.w500, fontSize: 16)), - ), - Divider(height: 2, color: theme.weakDividerColor), - TextField( - controller: _selectionController, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: const EdgeInsets.symmetric(vertical: 5), - height: 40, - child: Text( - tips, - style: - const TextStyle(color: Colors.grey, fontSize: 12), - ), - ) - ], - ), + if (isShowCancel) + Container( + margin: const EdgeInsets.only(right: 20), + child: SizedBox( + width: 84, + child: ElevatedButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + theme.wideBackgroundColor), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5))), + ), + onPressed: () { + if (entry != null) { + entry?.remove(); + entry = null; + } else { + Navigator.pop(context); + } + }, + child: Text( + TIM_t("取消"), + style: TextStyle(color: theme.darkTextColor), + )), + )), SizedBox( - width: double.infinity, + width: 84, child: ElevatedButton( style: ButtonStyle( shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(5))), ), onPressed: () { - String text = _selectionController.text; - // if (text == "") { - // _coreService.callOnCallback(TIMCallback( - // type: TIMCallbackType.INFO, - // infoRecommendText: TIM_t("输入不能为空"), - // infoCode: 6661401)); - // return; - // } + String text = selectionController.text; onSubmitted(text); - Navigator.pop(context); + if (entry != null) { + entry?.remove(); + entry = null; + } else { + Navigator.pop(context); + } }, - child: Text(TIM_t("确定"))), + child: Text(TIM_t("保存"))), ), ], ), - )); - }); + if (!isDesktopScreen) + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (isShowCancel) + Expanded( + child: Container( + margin: const EdgeInsets.only(right: 20), + child: ElevatedButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + theme.wideBackgroundColor), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5))), + ), + onPressed: () { + if (entry != null) { + entry?.remove(); + entry = null; + } else { + Navigator.pop(context); + } + }, + child: Text( + TIM_t("取消"), + style: TextStyle(color: theme.darkTextColor), + )), + )), + Expanded( + child: SizedBox( + child: ElevatedButton( + style: ButtonStyle( + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5))), + ), + onPressed: () { + String text = selectionController.text; + onSubmitted(text); + if (entry != null) { + entry?.remove(); + entry = null; + } else { + Navigator.pop(context); + } + }, + child: Text(TIM_t("确定"))), + )), + ], + ), + ], + ), + )); + } + + static showTextInputBottomSheet({ + required BuildContext context, + required String title, + String? tips, + required Function(String text) onSubmitted, + required TUITheme theme, + Offset? initOffset, + String? initText, + }) { + TextEditingController _selectionController = TextEditingController(); + final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop; + if (isDesktopScreen) { + if (entry != null) { + return; + } + entry = OverlayEntry(builder: (BuildContext context) { + return TUIKitDragArea( + closeFun: (){ + if(entry != null){ + entry?.remove(); + entry = null; + } + }, + initOffset: initOffset ?? + Offset(MediaQuery.of(context).size.height * 0.5 + 20, + MediaQuery.of(context).size.height * 0.5 - 100), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(8)), + color: theme.wideBackgroundColor, + border: Border.all( + width: 2, + color: theme.weakBackgroundColor ?? const Color(0xFFbebebe), + ), + boxShadow: const [ + BoxShadow( + color: Color(0xFFbebebe), + offset: Offset(5, 5), + blurRadius: 10, + spreadRadius: 1, + ), + ], + ), + child: SizedBox( + width: 350, + child: inputBoxContent( + context: context, + isShowCancel: true, + title: title, + tips: tips, + onSubmitted: onSubmitted, + theme: theme, + initText: initText, + selectionController: _selectionController), + ), + )); + }); + Overlay.of(context)?.insert(entry!); + } else { + showModalBottomSheet( + isScrollControlled: true, // !important + context: context, + builder: (BuildContext context) { + return inputBoxContent( + context: context, + title: title, + tips: tips, + initText: initText, + onSubmitted: onSubmitted, + theme: theme, + selectionController: _selectionController); + }); + } } } diff --git a/lib/ui/widgets/transimit_group_owner_select.dart b/lib/ui/widgets/transimit_group_owner_select.dart index 52f1ce3..8dbe873 100644 --- a/lib/ui/widgets/transimit_group_owner_select.dart +++ b/lib/ui/widgets/transimit_group_owner_select.dart @@ -5,34 +5,36 @@ import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; +import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart'; import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_member_search.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/group_member_list.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; -class SelectTransimitOwner extends StatefulWidget { +GlobalKey<_SelectNewGroupOwner> selectNewGroupOwnerKey = GlobalKey(); + +class SelectNewGroupOwner extends StatefulWidget { final String? groupID; final TUIGroupProfileModel model; - const SelectTransimitOwner({ + final ValueChanged>? onSelectedMember; + + const SelectNewGroupOwner({ this.groupID, Key? key, required this.model, + this.onSelectedMember, }) : super(key: key); @override - State createState() => _SelectCallInviterState(); + State createState() => _SelectNewGroupOwner(); } -class _SelectCallInviterState extends TIMUIKitState { +class _SelectNewGroupOwner extends TIMUIKitState { final CoreServicesImpl _coreServicesImpl = serviceLocator(); List selectedMember = []; List? searchMemberList; String? searchText; - @override - void initState() { - super.initState(); - } @override void dispose() { @@ -81,81 +83,86 @@ class _SelectCallInviterState extends TIMUIKitState { }); } + onSubmit() { + if (widget.onSelectedMember != null) { + widget.onSelectedMember!(selectedMember); + } + } + @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { final TUITheme theme = value.theme; - return Scaffold( - appBar: AppBar( - shadowColor: theme.weakBackgroundColor, - iconTheme: const IconThemeData( - color: Colors.white, - ), - flexibleSpace: Container( - decoration: BoxDecoration( - gradient: LinearGradient(colors: [ - theme.lightPrimaryColor ?? CommonColor.lightPrimaryColor, - theme.primaryColor ?? CommonColor.primaryColor - ]), - ), - ), - leading: TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: Text( - TIM_t("取消"), - style: const TextStyle( - color: Colors.white, - fontSize: 16, + Widget memberBody() { + return GroupProfileMemberList( + customTopArea: PlatformUtils().isWeb + ? null + : GroupMemberSearchTextField( + onTextChange: (text) => handleSearchGroupMembers(text, context), ), - ), - ), - actions: [ - TextButton( - onPressed: () { - if (selectedMember.isNotEmpty) { - Navigator.pop(context, selectedMember); - } - }, - child: Text( - TIM_t("完成"), - style: const TextStyle( - color: Colors.white, + memberList: (searchMemberList ?? widget.model.groupMemberList) + .where((element) => + element?.userID != _coreServicesImpl.loginInfo.userID) + .toList(), + canSlideDelete: false, + canSelectMember: true, + maxSelectNum: 1, + onSelectedMemberChange: (member) { + selectedMember = member; + setState(() {}); + }, + touchBottomCallBack: () {}, + ); + } + + return TUIKitScreenUtils.getDeviceWidget( + defaultWidget: Scaffold( + appBar: AppBar( + shadowColor: theme.weakBackgroundColor, + iconTheme: IconThemeData( + color: theme.appbarTextColor, + ), + backgroundColor: theme.appbarBgColor ?? + theme.primaryColor, + leading: TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text( + TIM_t("取消"), + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 16, + ), + ), + ), + actions: [ + TextButton( + onPressed: () { + if (selectedMember.isNotEmpty) { + Navigator.pop(context, selectedMember); + } + }, + child: Text( + TIM_t("完成"), + style: TextStyle( + color: theme.appbarTextColor, + fontSize: 16, + ), + ), + ) + ], + centerTitle: true, + leadingWidth: 100, + title: Text( + "转让群主", + style: TextStyle( + color: theme.appbarTextColor, fontSize: 16, ), ), - ) - ], - centerTitle: true, - leadingWidth: 100, - title: const Text( - "转让群主", - style: TextStyle( - color: Colors.white, - fontSize: 17, ), - ), - ), - body: GroupProfileMemberList( - customTopArea: PlatformUtils().isWeb - ? null - : GroupMemberSearchTextField( - onTextChange: (text) => - handleSearchGroupMembers(text, context), - ), - memberList: (searchMemberList ?? widget.model.groupMemberList) - .where((element) => - element?.userID != _coreServicesImpl.loginInfo.userID) - .toList(), - canSlideDelete: false, - canSelectMember: true, - maxSelectNum: 1, - onSelectedMemberChange: (member) { - selectedMember = member; - setState(() {}); - }, - touchBottomCallBack: () {}, - )); + body: memberBody()), + desktopWidget: memberBody()); } } diff --git a/lib/ui/widgets/video_screen.dart b/lib/ui/widgets/video_screen.dart index 58dcb0f..933cfd3 100644 --- a/lib/ui/widgets/video_screen.dart +++ b/lib/ui/widgets/video_screen.dart @@ -1,13 +1,13 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; - import 'package:crypto/crypto.dart'; +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:tencent_im_base/tencent_im_base.dart'; import 'package:extended_image/extended_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_chat_global_model.dart'; import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; @@ -18,7 +18,6 @@ import 'package:tencent_cloud_chat_uikit/ui/utils/permission.dart'; import 'package:tencent_cloud_chat_uikit/ui/utils/platform.dart'; import 'package:tencent_cloud_chat_uikit/ui/widgets/video_custom_control.dart'; import 'package:video_player/video_player.dart'; - import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; class VideoScreen extends StatefulWidget { @@ -79,27 +78,37 @@ class _VideoScreenState extends TIMUIKitState { xhr.send(); return; } - if (PlatformUtils().isIOS) { - if (!await Permissions.checkPermission( - context, - Permission.photosAddOnly.value, - )) { - return; - } - } else { - if (!await Permissions.checkPermission( - context, - Permission.storage.value, - )) { - return; + if(PlatformUtils().isMobile){ + if (PlatformUtils().isIOS) { + if (!await Permissions.checkPermission( + context, + Permission.photosAddOnly.value, + )) { + return; + } + } else { + final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; + if ((androidInfo.version.sdkInt ?? 0) >= 33) { + final videos = await Permissions.checkPermission( + context,Permission.videos.value, + ); + + if(!videos){ + return; + } + } else { + final storage = await Permissions.checkPermission( + context, Permission.storage.value, + ); + if(!storage){ + return; + } + } } } String savePath = videoUrl; if (!isAsset) { - // var appDocDir = await getTemporaryDirectory(); - // savePath = appDocDir.path + "/temp.mp4"; - // await Dio().download(videoUrl, savePath); - if (widget.message.msgID == null || widget.message.msgID!.isEmpty) { return; } @@ -296,7 +305,7 @@ class _VideoScreenState extends TIMUIKitState { widget.videoElement.localVideoUrl!, )); await player.initialize(); - WidgetsBinding.instance?.addPostFrameCallback((_) { + WidgetsBinding.instance.addPostFrameCallback((_) { double w = getVideoWidth(); double h = getVideoHeight(); ChewieController controller = ChewieController( diff --git a/lib/ui/widgets/wide_popup.dart b/lib/ui/widgets/wide_popup.dart new file mode 100644 index 0000000..e866ac0 --- /dev/null +++ b/lib/ui/widgets/wide_popup.dart @@ -0,0 +1,229 @@ +import 'package:flutter/material.dart'; +import 'package:tencent_cloud_chat_uikit/business_logic/view_models/tui_self_info_view_model.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/core/tim_uikit_wide_modal_operation_key.dart'; +import 'package:tencent_cloud_chat_uikit/data_services/services_locatar.dart'; +import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart'; +import 'package:tencent_cloud_chat_uikit/ui/widgets/drag_widget.dart'; + +class TUIKitWidePopup { + static OverlayEntry? entry; + + static showSecondaryConfirmDialog({ + required TUIKitWideModalOperationKey operationKey, + required BuildContext context, + required String text, + required TUITheme theme, + VoidCallback? onConfirm, + VoidCallback? onCancel, + }) { + return TUIKitWidePopup.showPopupWindow( + operationKey: operationKey, + context: context, + isDarkBackground: false, + onCancel: onCancel, + onConfirm: onConfirm, + width: 350, + height: 120, + child: (onClose) => Container( + padding: const EdgeInsets.only(left: 16, right: 16), + child: Row( + children: [ + Icon(Icons.info, color: theme.primaryColor), + const SizedBox( + width: 8, + ), + Expanded(child: Text(text)) + ], + ), + )); + } + + static showPopupWindow({ + /// You could determine this field as `TUIKitWideModalOperationKey.custom` for your own business needs. + required TUIKitWideModalOperationKey operationKey, + required BuildContext context, + required Widget Function(VoidCallback closeFunc) child, + TUITheme? theme, + double? width, + double? height, + Offset? offset, + String? initText, + BorderRadius? borderRadius, + bool isDarkBackground = true, + String? title, + VoidCallback? onSubmit, + Widget? submitWidget, + VoidCallback? onConfirm, + VoidCallback? onCancel, + }) async { + + final TUISelfInfoViewModel selfInfoViewModel = + serviceLocator(); + + if(selfInfoViewModel.globalConfig?.showDesktopModalFunc != null){ + final res = await selfInfoViewModel.globalConfig!.showDesktopModalFunc!( + operationKey, + context, + child, + theme, + width, + height, + offset, + initText, + borderRadius, + isDarkBackground, + title, + onSubmit, + submitWidget, + onConfirm, + onCancel + ); + + if(res == true){ + return; + } + } + + if (entry != null) { + return; + } + entry = OverlayEntry(builder: (BuildContext context) { + return TUIKitDragArea( + backgroundColor: isDarkBackground ? const Color(0x7F000000) : null, + closeFun: () { + if (entry != null) { + entry?.remove(); + entry = null; + } + }, + initOffset: offset ?? + (width != null && height != null + ? Offset(MediaQuery.of(context).size.width * 0.5 - width / 2, + MediaQuery.of(context).size.height * 0.5 - height / 2) + : null), + child: Container( + width: width, + height: height, + decoration: BoxDecoration( + borderRadius: + borderRadius ?? const BorderRadius.all(Radius.circular(16)), + color: theme?.wideBackgroundColor ?? const Color(0xFFffffff), + border: isDarkBackground + ? Border.all( + width: 2, + color: + theme?.weakBackgroundColor ?? const Color(0xFFbebebe), + ) + : null, + boxShadow: isDarkBackground + ? null + : const [ + BoxShadow( + color: Color(0xFFbebebe), + offset: Offset(3, 3), + blurRadius: 10, + spreadRadius: 1, + ), + ], + ), + child: Column( + children: [ + if (title != null) + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: hexToColor("f5f6f7"), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16)), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + Text( + title, + style: TextStyle( + fontSize: 18, + color: theme?.darkTextColor ?? + const Color(0xFF444444)), + ), + InkWell( + onTap: () { + if (onSubmit != null) { + onSubmit(); + } + entry?.remove(); + entry = null; + }, + child: onSubmit != null + ? (submitWidget ?? const Icon(Icons.check)) + : const Icon(Icons.close), + ) + ], + ), + ), + if (title != null) + SizedBox( + height: 1, + child: Container( + color: theme?.weakDividerColor ?? const Color(0xFFE5E6E9), + ), + ), + if (height != null && width != null) + Expanded(child: child(() { + entry?.remove(); + entry = null; + })), + if (height == null || width == null) + child(() { + entry?.remove(); + entry = null; + }), + if (onCancel != null || onConfirm != null) + Container( + padding: const EdgeInsets.only(bottom: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (onCancel != null) + Container( + margin: const EdgeInsets.only(right: 16), + child: OutlinedButton( + onPressed: () { + entry?.remove(); + entry = null; + onCancel(); + }, + child: Text( + TIM_t("取消"), + style: TextStyle( + color: + theme?.weakTextColor ?? Colors.black), + )), + ), + if (onConfirm != null) + Container( + margin: const EdgeInsets.only(right: 16), + child: ElevatedButton( + onPressed: () { + entry?.remove(); + entry = null; + onConfirm(); + }, + child: Text( + TIM_t("确定"), + style: TextStyle(color: theme?.primaryColor), + )), + ), + ], + ), + ) + ], + ), + )); + }); + Overlay.of(context)?.insert(entry!); + + } +} diff --git a/pubspec.lock b/pubspec.lock index 754acb8..48af976 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "569ddca58d535e601dd1584afa117710abc999d036c0cd2c51777fb257df78e8" + sha256: "3444216bfd127af50bbe4862d8843ed44db946dd933554f0d7285e89f10e28ac" url: "https://pub.dev" source: hosted - version: "53.0.0" + version: "50.0.0" adaptive_action_sheet: dependency: "direct main" description: @@ -21,34 +21,90 @@ packages: dependency: transitive description: name: analyzer - sha256: "10927c4b7c7c88b1adbca278c3d5531db92e2f4b4abf04e2919a800af965f3f5" + sha256: "68796c31f510c8455a06fed75fc97d8e5ad04d324a830322ab3efc9feb6201c1" url: "https://pub.dev" source: hosted - version: "5.5.0" + version: "5.2.0" args: dependency: transitive description: name: args - sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + sha256: b003c3098049a51720352d219b0bb5f219b60fbfb68e7a4748139a06a5676515 url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.3.1" async: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "271b8899fc99f9df4f4ed419fa14e2fff392c7b2c162fbb87b222e2e963ddc73" url: "https://pub.dev" source: hosted - version: "2.10.0" - azlistview: + version: "2.9.0" + audioplayers: dependency: "direct main" description: - name: azlistview - sha256: "93e865f11777a271b439f0d6b00799c0797e9daeec2e082a2e01373809c4b90d" + name: audioplayers + sha256: "16451eab798b23ad9307aef6f9ca62bb8fb06542af8810eead0d236d3fd40a42" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + audioplayers_android: + dependency: transitive + description: + name: audioplayers_android + sha256: b2c833e6f718b6b030454e329931229afafe9327fdb002874dd544dc8bf2484d url: "https://pub.dev" source: hosted version: "2.0.0" + audioplayers_darwin: + dependency: transitive + description: + name: audioplayers_darwin + sha256: e7a3c8759bf11ecfe4b20df338bf9f3d37c7719a5761c46a3833aba0ceeaacff + url: "https://pub.dev" + source: hosted + version: "3.0.1" + audioplayers_linux: + dependency: transitive + description: + name: audioplayers_linux + sha256: e95b65e1f4d4764601dac5e65f8d8186fc29401043ab020f1dacec483d708707 + url: "https://pub.dev" + source: hosted + version: "1.0.4" + audioplayers_platform_interface: + dependency: transitive + description: + name: audioplayers_platform_interface + sha256: "178581a44cb685fd798d2108111d2e98cca3400e30b9c3a05546f124fb37f600" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + audioplayers_web: + dependency: transitive + description: + name: audioplayers_web + sha256: "859ba09be2a57e57a787273f18c8cf0d9b61383870c5ee4b5632fe9adbc37edf" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + audioplayers_windows: + dependency: transitive + description: + name: audioplayers_windows + sha256: "622e01c4c357c2aaf1b956c3a0f89d97c3cb40315c03f16e3b6c2a31ff9c38bc" + url: "https://pub.dev" + source: hosted + version: "1.1.3" + azlistview_all_platforms: + dependency: "direct main" + description: + name: azlistview_all_platforms + sha256: "47ce2204863e0c3e481ca2a3813096d9818b153f1f677e839503e33d36e97993" + url: "https://pub.dev" + source: hosted + version: "2.1.2" build: dependency: transitive description: @@ -69,18 +125,18 @@ packages: dependency: transitive description: name: build_daemon - sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf" + sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: db49b8609ef8c81cca2b310618c3017c00f03a92af44c04d310b907b2d692d95 + sha256: "687cf90a3951affac1bd5f9ecb5e3e90b60487f3d9cdc359bb310f8876bb02a6" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.0.10" build_runner: dependency: "direct dev" description: @@ -109,76 +165,76 @@ packages: dependency: transitive description: name: built_value - sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725" + sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0" url: "https://pub.dev" source: hosted - version: "8.4.3" + version: "8.4.4" cached_network_image: dependency: "direct main" description: name: cached_network_image - sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 + sha256: e764e48ef036cabdf84319ba7b8b5871b6b43266e14de787cb43f77639089ae5 url: "https://pub.dev" source: hosted - version: "3.2.3" + version: "3.2.1" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface - sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 + sha256: "8e2b5befefec5063bee8f209fda21751f6328d405d4237c70f21104568b2fee7" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "1.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web - sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 + sha256: d4351c7eb16767df129b0474a5ebc4e028870379c063e8ba265a56aa00831e70 url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.1" camera: dependency: transitive description: name: camera - sha256: e7ac55af24a890d20276821eb3c95857074d03b7de6f9892b99a205ee30bd179 + sha256: ad1c53c554a2f3e5708f3b01eb738d60b902bb61f7f4ad420c65c715e65a7379 url: "https://pub.dev" source: hosted - version: "0.10.3" + version: "0.10.3+2" camera_android: dependency: transitive description: name: camera_android - sha256: e491c836147f60dd8a54cf3895fd2960e13b21b78a9d15b563a1b6c70894f142 + sha256: "16e46b32915fcbc53afc1f96ca868cd91495608935a20bd16f47b854bfed9b17" url: "https://pub.dev" source: hosted - version: "0.10.4" + version: "0.10.4+3" camera_avfoundation: dependency: transitive description: name: camera_avfoundation - sha256: "6a68c20593d4cd58974d555f74a48b244f9db28cc9156de57781122d11b8754b" + sha256: c328d477e5af88b3edcf277183c3b68f6e73b0f4e4e1053a22026e1c175e5bdb url: "https://pub.dev" source: hosted - version: "0.9.11" + version: "0.9.11+1" camera_platform_interface: dependency: transitive description: name: camera_platform_interface - sha256: b632be28e61d00a233f67d98ea90fd7041956f27a1c65500188ee459be60e15f + sha256: "00d972adee2e8a282b4d7445e8e694aa1dc0c36b70455b99afa96fbf5e814119" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" camera_web: dependency: transitive description: name: camera_web - sha256: "496de93c5d462738ce991dbfe91fb19026f115ed36406700a20a380fb0018299" + sha256: d77965f32479ee6d8f48205dcf10f845d7210595c6c00faa51eab265d1cae993 url: "https://pub.dev" source: hosted - version: "0.3.1+1" + version: "0.3.1+3" characters: - dependency: "direct main" + dependency: transitive description: name: characters sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c @@ -197,10 +253,10 @@ packages: dependency: transitive description: name: checked_yaml - sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + sha256: dd007e4fb8270916820a0d66e24f619266b60773cddd082c6439341645af2659 url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.1" chewie: dependency: "direct main" description: @@ -237,12 +293,12 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: "1be13198012c1d5bc042dc40ad1d7f16cbd522350984c0c1abf471d6d7e305c6" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.0" cross_file: - dependency: transitive + dependency: "direct main" description: name: cross_file sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" @@ -285,10 +341,74 @@ packages: dependency: transitive description: name: dart_style - sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4" + sha256: "5be16bf1707658e4c03078d4a9b90208ded217fb02c163e207d334082412f2fb" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.5" + desktop_drop: + dependency: "direct main" + description: + name: desktop_drop + sha256: "4ca4d960f4b11c032e9adfd2a0a8ac615bc3fddb4cbe73dcf840dd8077582186" + url: "https://pub.dev" + source: hosted + version: "0.4.1" + device_info_plus: + dependency: "direct main" + description: + name: device_info_plus + sha256: b809c4ed5f7fcdb325ccc70b80ad934677dc4e2aa414bf46859a42bfdfafcbb6 + url: "https://pub.dev" + source: hosted + version: "4.1.3" + device_info_plus_linux: + dependency: transitive + description: + name: device_info_plus_linux + sha256: "77a8b3c4af06bc46507f89304d9f49dfc64b4ae004b994532ed23b34adeae4b3" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_macos: + dependency: transitive + description: + name: device_info_plus_macos + sha256: "37961762fbd46d3620c7b69ca606671014db55fc1b7a11e696fd90ed2e8fe03d" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: "83fdba24fcf6846d3b10f10dfdc8b6c6d7ada5f8ed21d62ea2909c2dfa043773" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_web: + dependency: transitive + description: + name: device_info_plus_web + sha256: "5890f6094df108181c7a29720bc23d0fd6159f17d82787fac093d1fefcaf6325" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + device_info_plus_windows: + dependency: transitive + description: + name: device_info_plus_windows + sha256: "23a2874af0e23ee6e3a2a0ebcecec3a9da13241f2cb93a93a44c8764df123dd7" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + diff_match_patch: + dependency: "direct main" + description: + name: diff_match_patch + sha256: "2efc9e6e8f449d0abe15be240e2c2a3bcd977c8d126cfd70598aee60af35c0a4" + url: "https://pub.dev" + source: hosted + version: "0.4.1" disk_space: dependency: "direct main" description: @@ -309,18 +429,18 @@ packages: dependency: "direct main" description: name: extended_image - sha256: a6b738d9b8d5513be72c545cc3e9c5c451fbee77c8db3cbec7c32ae85b82fb93 + sha256: a417f57e0434fc739c435e456ceace53753304157e85f77acaa680b266d4a7d8 url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.2.2" extended_image_library: dependency: transitive description: name: extended_image_library - sha256: b1de389378589e4dffb3564d782373238f19064037458092c49b3043b2791b2b + sha256: "83285a9286db7d96154dc427d9c56cf00fb5931a2ce369efb707804d7461a896" url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "3.3.0" fast_i18n: dependency: "direct dev" description: @@ -329,14 +449,22 @@ packages: url: "https://pub.dev" source: hosted version: "5.12.6" + fc_native_video_thumbnail_for_us: + dependency: "direct main" + description: + name: fc_native_video_thumbnail_for_us + sha256: db6fa2998195ef5eadac690ae58d6a909ddb5b0283ebbbf9ae4e0e8f99a54902 + url: "https://pub.dev" + source: hosted + version: "0.4.8+1" ffi: dependency: transitive description: name: ffi - sha256: "13a6ccf6a459a125b3fcdb6ec73bd5ff90822e071207c663bfd1f70062d51d18" + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "2.0.1" file: dependency: transitive description: @@ -349,10 +477,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "704259669b5e9cb24e15c11cfcf02caf5f20d30901b3916d60b6d1c2d647035f" + sha256: dcde5ad1a0cebcf3715ea3f24d0db1888bf77027a26c77d7779e8ef63b8ade62 url: "https://pub.dev" source: hosted - version: "4.6.1" + version: "5.2.9" file_utils: dependency: transitive description: @@ -365,10 +493,10 @@ packages: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: "04be3e934c52e082558cc9ee21f42f5c1cd7a1262f4c63cd0357c08d5bba81ec" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.0.1" flutter: dependency: "direct main" description: flutter @@ -414,11 +542,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" - flutter_localizations: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" flutter_markdown: dependency: "direct main" description: @@ -431,10 +554,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b" + sha256: c224ac897bed083dabf11f238dd11a239809b446740be0c2044608c50029ffdf url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.9" flutter_plugin_record_plus: dependency: "direct main" description: @@ -451,14 +574,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - flutter_spinkit: - dependency: "direct main" - description: - name: flutter_spinkit - sha256: "77a2117c0517ff909221f3160b8eb20052ab5216107581168af574ac1f05dff8" - url: "https://pub.dev" - source: hosted - version: "5.1.0" flutter_svg: dependency: "direct main" description: @@ -516,10 +631,10 @@ packages: dependency: transitive description: name: html - sha256: d9793e10dbe0e6c364f4c59bf3e01fb33a9b2a674bc7a1081693dba0614b6269 + sha256: "79d498e6d6761925a34ee5ea8fa6dfef38607781d2fa91e37523474282af55cb" url: "https://pub.dev" source: hosted - version: "0.15.1" + version: "0.15.2" http: dependency: "direct main" description: @@ -564,42 +679,42 @@ packages: dependency: "direct main" description: name: image_picker - sha256: d39cc12402dab8365fe5b5370e64694ae0223d675c36b15ff0490b7cc3d32551 + sha256: "64b21d9f0e065f9ab0e4dde458076226c97382cc0c6949144cb874c62bf8e9f8" url: "https://pub.dev" source: hosted - version: "0.8.6+2" + version: "0.8.7" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "385f12ee9c7288575572c7873a332016ec45ebd092e1c2f6bd421b4a9ad21f1d" + sha256: "420ed22d2c9ce767ed96df723aaebfeb20ce92dfda8665cd2ba72d72a51ae669" url: "https://pub.dev" source: hosted - version: "0.8.5+6" + version: "0.8.6+1" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "7d319fb74955ca46d9bf7011497860e3923bb67feebcf068f489311065863899" + sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c" url: "https://pub.dev" source: hosted - version: "2.1.10" + version: "2.1.12" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: "884ed71165bc01ffe1b0b7813e6fa17e1e9442da974656f99b79a292371303d6" + sha256: "39aa70b5f1e5e7c94585b9738632d5fdb764a5655e40cd9e7b95fbd2fc50c519" url: "https://pub.dev" source: hosted - version: "0.8.6+8" + version: "0.8.6+9" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: "7cef2f28f4f2fef99180f636c3d446b4ccbafd6ba0fad2adc9a80c4040f656b8" + sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8" url: "https://pub.dev" source: hosted - version: "2.6.2" + version: "2.6.3" intl: dependency: "direct main" description: @@ -617,7 +732,7 @@ packages: source: hosted version: "1.0.4" js: - dependency: "direct main" + dependency: transitive description: name: js sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" @@ -625,13 +740,13 @@ packages: source: hosted version: "0.6.5" json_annotation: - dependency: "direct main" + dependency: transitive description: name: json_annotation - sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 + sha256: "3520fa844009431b5d4491a5a778603520cdc399ab3406332dcc50f93547258c" url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.7.0" link_preview_generator: dependency: "direct main" description: @@ -660,10 +775,10 @@ packages: dependency: transitive description: name: logging - sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + sha256: c0bbfe94d46aedf9b8b3e695cf3bd48c8e14b35e3b2c639e0aa7755d589ba946 url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.0" lpinyin: dependency: "direct main" description: @@ -684,10 +799,10 @@ packages: dependency: transitive description: name: matcher - sha256: c94db23593b89766cda57aab9ac311e3616cf87c6fa4e9749df032f66f30dcb8 + sha256: "80c2989398773fa06e2457e9ff08580f24e9858b28462a722241cb53e5613478" url: "https://pub.dev" source: hosted - version: "0.12.14" + version: "0.12.12" material_color_utilities: dependency: transitive description: @@ -708,10 +823,10 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "52e38f7e1143ef39daf532117d6b8f8f617bf4bcd6044ed8c29040d20d269630" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.3" nested: dependency: transitive description: @@ -740,10 +855,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "7a6114becdf042be2b0777d77ace954d4a205644171a1cbd8712976b9bbb837c" + sha256: f62d7253edc197fe3c88d7c2ddab82d68f555e778d55390ccc3537eca8e8d637 url: "https://pub.dev" source: hosted - version: "1.4.2" + version: "1.4.3+1" package_info_plus_linux: dependency: transitive description: @@ -780,12 +895,20 @@ packages: dependency: transitive description: name: package_info_plus_windows - sha256: a6040b8695c82f8dd3c3d4dfab7ef96fbe9c67aac21b9bcf5db272589ef84441 + sha256: "79524f11c42dd9078b96d797b3cf79c0a2883a50c4920dc43da8562c115089bc" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "2.1.0" + pasteboard: + dependency: "direct main" + description: + name: pasteboard + sha256: "1c8b6a8b3f1d12e55d4e9404433cda1b4abe66db6b17bc2d2fb5965772c04674" + url: "https://pub.dev" + source: hosted + version: "0.2.0" path: - dependency: transitive + dependency: "direct main" description: name: path sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b @@ -812,50 +935,50 @@ packages: dependency: "direct main" description: name: path_provider - sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 + sha256: "04890b994ee89bfa80bf3080bfec40d5a92c5c7a785ebb02c13084a099d2b6f9" url: "https://pub.dev" source: hosted - version: "2.0.12" + version: "2.0.13" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e + sha256: "019f18c9c10ae370b08dce1f3e3b73bc9f58e7f087bb5e921f06529438ac0ae7" url: "https://pub.dev" source: hosted - version: "2.0.22" + version: "2.0.24" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" + sha256: "026b97a6c29da75181a37aae2eba9227f5fe13cb2838c6b975ce209328b8ab4e" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.3" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: "2e32f1640f07caef0d3cb993680f181c79e54a3827b997d5ee221490d131fbd9" + sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1" url: "https://pub.dev" source: hosted - version: "2.1.8" + version: "2.1.10" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 + sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.0.6" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905 + sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130 url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.1.5" pedantic: dependency: transitive description: @@ -908,10 +1031,10 @@ packages: dependency: transitive description: name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + sha256: "2ebb289dc4764ec397f5cd3ca9881c6d17196130a7d646ed022a0dd9c2e25a71" url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.0.0" photo_manager: dependency: transitive description: @@ -920,14 +1043,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.5.2" - photo_view: - dependency: "direct main" - description: - name: photo_view - sha256: "8036802a00bae2a78fc197af8a158e3e2f7b500561ed23b4c458107685e645bb" - url: "https://pub.dev" - source: hosted - version: "0.14.0" platform: dependency: transitive description: @@ -940,10 +1055,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" pool: dependency: transitive description: @@ -1008,70 +1123,70 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" - scrollable_positioned_list: + scrollable_positioned_list_for_us: dependency: transitive description: - name: scrollable_positioned_list - sha256: "9566352ab9ba05794ee6c8864f154afba5d36c5637d0e3e32c615ba4ceb92772" + name: scrollable_positioned_list_for_us + sha256: b5bcbb35114902c004a4f98f2dbd5b0a5a7f80a0144a8b46297601e38fa5383d url: "https://pub.dev" source: hosted - version: "0.2.3" + version: "0.4.2" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: "5949029e70abe87f75cfe59d17bf5c397619c4b74a099b10116baeb34786fad9" + sha256: ee6257848f822b8481691f20c3e6d2bfee2e9eccb2a3d249907fcfb198c55b41 url: "https://pub.dev" source: hosted - version: "2.0.17" + version: "2.0.18" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "955e9736a12ba776bdd261cf030232b30eadfcd9c79b32a3250dd4a494e8c8f7" + sha256: ad423a80fe7b4e48b50d6111b3ea1027af0e959e49d485712e134863d9c1c521 url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.0.17" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "2b55c18636a4edc529fa5cd44c03d3f3100c00513f518c5127c951978efcccd0" + sha256: "1e755f8583229f185cfca61b1d80fb2344c9d660e1c69ede5450d8f478fa5310" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.5" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: f8ea038aa6da37090093974ebdcf4397010605fd2ff65c37a66f9d28394cb874 + sha256: "3a59ed10890a8409ad0faad7bb2957dab4b92b8fbe553257b05d30ed8af2c707" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.5" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 + sha256: "824bfd02713e37603b2bdade0842e47d56e7db32b1dcdd1cae533fb88e2913fc" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 + sha256: "0dc2633f215a3d4aa3184c9b2c5766f4711e4e5a6b256e62aafee41f89f1bfb8" url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.0.6" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "5eaf05ae77658d3521d0e993ede1af962d4b326cd2153d312df716dc250f00c9" + sha256: "71bcd669bb9cdb6b39f22c4a7728b6d49e934f6cba73157ffa5a54f1eed67436" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.5" shelf: dependency: transitive description: @@ -1113,26 +1228,26 @@ packages: dependency: transitive description: name: sqflite - sha256: "78324387dc81df14f78df06019175a86a2ee0437624166c382e145d0a7fd9a4f" + sha256: b3a8307b9519af28518e271e548594bdc435225fc77e8fb22e71a296c69281cf url: "https://pub.dev" source: hosted - version: "2.2.4+1" + version: "2.0.3+1" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: bfd6973aaeeb93475bc0d875ac9aefddf7965ef22ce09790eb963992ffc5183f + sha256: "4aa3b917d48f9a3161419efa4a901e33a38721bf9a7465e7e07d2d6ef8895276" url: "https://pub.dev" source: hosted - version: "2.4.2+2" + version: "2.4.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: f8d9f247e2f9f90e32d1495ff32dac7e4ae34ffa7194c5ff8fcc0fd0e52df774 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.10.0" stream_channel: dependency: transitive description: @@ -1153,18 +1268,18 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "862015c5db1f3f3c4ea3b94dc2490363a84262994b88902315ed74be1155612f" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.1.1" synchronized: dependency: transitive description: name: synchronized - sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b" + sha256: "7b530acd9cb7c71b0019a1e7fa22c4105e675557a4400b6a401c71c5e0ade1ac" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.0+3" system_info2: dependency: transitive description: @@ -1177,26 +1292,34 @@ packages: dependency: transitive description: name: tencent_cloud_chat_sdk - sha256: "32b7e40c5a1682b3ee85daa73504af3d0d4e60a93472b279591e769b15b4861c" + sha256: "765a93262a41080e155ce5b8a6ca20147a81c7d306f7f87444077c5eaae87e08" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.1.5" + tencent_cloud_uikit_core: + dependency: "direct main" + description: + name: tencent_cloud_uikit_core + sha256: "829dfde0c4fbdae019ba233f7f2c299e7cbd18c3ae20ecfe3ab4a43084a33064" + url: "https://pub.dev" + source: hosted + version: "1.0.2" tencent_extended_text: dependency: "direct main" description: name: tencent_extended_text - sha256: cf0d283c01a9e63f75666d8b5b1cabd463e18e51802bf1d093d7a65bd369b3d4 + sha256: "2904d064eeb9d3395f7d31bdc9f168ee75e7783f20161b1a6eb4647677a56721" url: "https://pub.dev" source: hosted - version: "1.0.2+1" + version: "1.0.0" tencent_extended_text_field: dependency: "direct main" description: name: tencent_extended_text_field - sha256: daa10f3775bfac1cc841b34275c2746ced7764f3b77222a93edb4c13bad1209b + sha256: "4bb5bb3863792b7cee48d76cd100b0084906baa2bf4e1a917283f5de62076b0b" url: "https://pub.dev" source: hosted - version: "1.0.1+2" + version: "1.0.0" tencent_extended_text_library: dependency: transitive description: @@ -1209,18 +1332,18 @@ packages: dependency: "direct main" description: name: tencent_im_base - sha256: b5917ff0bae7c31d52f54932349fc400d3752719a1c5a2f0209258f85c7a6c07 + sha256: "516356a80f43b94a6c0719b54e4c641cb1f164830b2b3e887d175ae862ebab3f" url: "https://pub.dev" source: hosted - version: "1.0.26" + version: "1.0.51" tencent_im_sdk_plugin_platform_interface: dependency: transitive description: name: tencent_im_sdk_plugin_platform_interface - sha256: "7aff6a8495eae3efc3aed1ed944bab7a0ce7eb1035d09b3f3d7974bcb3d8b137" + sha256: "04043582f1af698b4abe12d53cd0f043466228fae712677688988d8ff7bfc1f1" url: "https://pub.dev" source: hosted - version: "0.3.12" + version: "0.3.19" tencent_keyboard_visibility: dependency: "direct main" description: @@ -1233,10 +1356,10 @@ packages: dependency: "direct main" description: name: tencent_open_file - sha256: "98cbffe55e3245a308fbf76e18c9a0f808e534c624bc1a1cc0a00bd63a418290" + sha256: "01f94f618da42e5593bbad0657fcd13cfc1c2360cca805d8cdfefe898cbe5429" url: "https://pub.dev" source: hosted - version: "4.0.9+1" + version: "4.0.10" tencent_super_tooltip: dependency: "direct main" description: @@ -1265,10 +1388,10 @@ packages: dependency: "direct main" description: name: tim_ui_kit_sticker_plugin - sha256: cd5d6e2380deaf73e420602bbfe3da36c0f3253adc531f76e139efec80671175 + sha256: "2a825d33076f319f6c1c87d58e2b0d650c9284ae4afd8efdc206f3e6f3582e64" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "2.0.1" timing: dependency: transitive description: @@ -1305,10 +1428,10 @@ packages: dependency: "direct main" description: name: universal_html - sha256: b5061c64c7c863c12e46279e032976f1c274f927fb3589b52b5928dcd2d52f7c + sha256: ed4f24120c9b1b4721d44e439f7a47d09d9f1b7b868bc84c9d6d373a4a8732af url: "https://pub.dev" source: hosted - version: "2.0.9" + version: "2.2.1" universal_io: dependency: transitive description: @@ -1321,66 +1444,66 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: e8f2efc804810c0f2f5b485f49e7942179f56eabcfe81dce3387fec4bb55876b + sha256: "75f2846facd11168d007529d6cd8fcb2b750186bea046af9711f10b907e1587e" url: "https://pub.dev" source: hosted - version: "6.1.9" + version: "6.1.10" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "3e2f6dfd2c7d9cd123296cab8ef66cfc2c1a13f5845f42c7a0f365690a8a7dd1" + sha256: "845530e5e05db5500c1a4c1446785d60cbd8f9bd45e21e7dd643a3273bb4bbd1" url: "https://pub.dev" source: hosted - version: "6.0.23" + version: "6.0.25" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "0a5af0aefdd8cf820dd739886efb1637f1f24489900204f50984634c07a54815" + sha256: bb328b24d3bccc20bdf1024a0990ac4f869d57663660de9c936fb8c043edefe3 url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.0.18" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "318c42cba924e18180c029be69caf0a1a710191b9ec49bb42b5998fdcccee3cc" + sha256: "206fb8334a700ef7754d6a9ed119e7349bc830448098f21a69bf1b4ed038cabc" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.4" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "41988b55570df53b3dd2a7fc90c76756a963de6a8c5f8e113330cb35992e2094" + sha256: "0ef2b4f97942a16523e51256b799e9aa1843da6c60c55eefbfa9dbc2dcb8331a" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.4" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6" + sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "44d79408ce9f07052095ef1f9a693c258d6373dc3944249374e30eff7219ccb0" + sha256: "81fe91b6c4f84f222d186a9d23c73157dc4c8e1c71489c4d08be1ad3b228f1aa" url: "https://pub.dev" source: hosted - version: "2.0.14" + version: "2.0.16" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: b6217370f8eb1fd85c8890c539f5a639a01ab209a36db82c921ebeacefc7a615 + sha256: a83ba3607a507758669cfafb03f9de09bf6e6280c14d9b9cb18f013e406dcacd url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" uuid: dependency: "direct main" description: @@ -1401,50 +1524,42 @@ packages: dependency: "direct main" description: name: video_player - sha256: "59f7f31c919c59cbedd37c617317045f5f650dc0eeb568b0b0de9a36472bdb28" + sha256: "868a139229acb5018d22aded3eb9cb4767ff43a8216573c086b6c535a4957481" url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.6.0" video_player_android: dependency: transitive description: name: video_player_android - sha256: "984388511230bac63feb53b2911a70e829fe0976b6b2213f5c579c4e0a882db3" + sha256: dc31c60ae591aa3ccb2d460c3690ceceb86cbb826e73428d817a37650dc4e229 url: "https://pub.dev" source: hosted - version: "2.3.10" + version: "2.4.2" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: d9f7a46d6a77680adb03ec05a381025d6e890ebe636637c6c3014cc3926b97e9 + sha256: "5df5411ff9d316f1dcbfee284e9838aa686e314f2a722b15c02cb7ce40ef9446" url: "https://pub.dev" source: hosted - version: "2.3.8" + version: "2.3.9" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: "42bb75de5e9b79e1f20f1d95f688fac0f95beac4d89c6eb2cd421724d4432dae" + sha256: "72ba04ad0eff76123c6d782ac46621cb8be476a89c33c89173fce982b6ec049b" url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.0.2" video_player_web: dependency: transitive description: name: video_player_web - sha256: b649b07b8f8f553bee4a97a0a53d0fe78a70b115eafaf0105b612b32b05ddb99 + sha256: fb3bbeaf0302cb0c31340ebd6075487939aa1fe3b379d1a8784ef852b679940e url: "https://pub.dev" source: hosted - version: "2.0.13" - video_thumbnail: - dependency: "direct main" - description: - name: video_thumbnail - sha256: "3455c189d3f0bb4e3fc2236475aa84fe598b9b2d0e08f43b9761f5bc44210016" - url: "https://pub.dev" - source: hosted - version: "0.5.3" + version: "2.0.15" wakelock: dependency: transitive description: @@ -1481,10 +1596,10 @@ packages: dependency: transitive description: name: wakelock_windows - sha256: "108b1b73711f1664ee462e73af34a9286ff496e27d4d8371e2fb4da8fde4cdac" + sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.1" watcher: dependency: transitive description: @@ -1513,10 +1628,10 @@ packages: dependency: transitive description: name: win32 - sha256: c0e3a4f7be7dae51d8f152230b86627e3397c1ba8c3fa58e63d44a9f3edc9cef + sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4 url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "3.1.4" xdg_directories: dependency: transitive description: @@ -1529,10 +1644,10 @@ packages: dependency: transitive description: name: xml - sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.1.0" yaml: dependency: transitive description: @@ -1542,5 +1657,5 @@ packages: source: hosted version: "3.1.1" sdks: - dart: ">=2.19.0 <4.0.0" - flutter: ">=3.7.0" + dart: ">=2.17.0 <3.0.0" + flutter: ">=3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 0d7aa5b..47a3703 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,24 +1,25 @@ name: tencent_cloud_chat_uikit -description: Chat UI components library and basic chat business logic for Tencent Cloud Chat, helping you build In-APP Chat module easily. -version: 1.7.0+1 +description: A powerful chat UI component library and business logic for Tencent Cloud Chat, creating seamless in-app chat modules for delightful user experiences. +version: 2.0.0 homepage: https://www.tencentcloud.com/products/im?from=pub -repository: https://github.com/TencentCloud/chat-uikit-flutter +repository: https://github.com/TencentCloud/tc-chat-uikit-flutter documentation: https://comm.qq.com/im/doc/flutter/en/TUIKit/readme.html + # publish_to: none platforms: android: ios: + macos: web: + windows: environment: - sdk: ">=2.15.0 <3.0.0" - flutter: ">=2.10.0" + sdk: ">=2.17.0 <3.0.0" + flutter: ">=3.0.0" dependencies: flutter: sdk: flutter - flutter_localizations: - sdk: flutter adaptive_action_sheet: ^2.0.1 provider: ^6.0.1 intl: ^0.17.0 @@ -26,50 +27,53 @@ dependencies: dotted_border: ^2.0.0+2 flutter_svg: ^1.0.0 image_picker: ^0.8.5+3 - file_picker: ^4.6.1 + file_picker: ^5.2.9 tencent_super_tooltip: ^0.0.1 video_player: ^2.4.2 chewie: ^1.3.2 flutter_slidable_for_tencent_im: ^1.4.0 flutter_plugin_record_plus: ^0.0.15 - azlistview: ^2.0.0 + azlistview_all_platforms: ^2.1.2 lpinyin: ^2.0.3 transparent_image: ^2.0.0 - video_thumbnail: ^0.5.2 image_gallery_saver: ^1.7.1 - photo_view: ^0.14.0 path_provider: ^2.0.8 - characters: ^1.1.0 cached_network_image: ^3.2.0 shared_preferences: ^2.0.13 - json_annotation: ^4.4.0 - js: ^0.6.3 scroll_to_index: ^2.1.1 wechat_assets_picker: ^7.2.0 tencent_wechat_camera_picker: ^3.6.5 flutter_easyrefresh: ^2.2.1 - flutter_spinkit: ^5.1.0 extended_image: ^6.0.2+1 tencent_extended_text_field: ^1.0.0 tencent_extended_text: ^1.0.0 package_info_plus: ^1.4.0 loading_animation_widget: ^1.1.0+3 - permission_handler: ^10.0.0 + permission_handler: ^10.2.0 tuple: ^2.0.0 flutter_markdown: ^0.6.9 url_launcher: ^6.1.4 universal_html: ^2.0.8 link_preview_generator: ^1.2.0 - tencent_im_base: ^1.0.26 disk_space: ^0.2.1 http: ^0.13.5 crypto: ^3.0.2 collection: ^1.15.0 flutter_image_compress: ^1.1.3 uuid: ^3.0.6 - tencent_open_file: ^4.0.9 + tencent_open_file: ^4.0.10 tencent_keyboard_visibility: ^1.0.1 - tim_ui_kit_sticker_plugin: ^1.2.0 + tim_ui_kit_sticker_plugin: ^2.0.1 + tencent_im_base: ^1.0.51 + fc_native_video_thumbnail_for_us: ^0.4.8+1 + audioplayers: ^3.0.1 + path: ^1.8.1 + tencent_cloud_uikit_core: ^1.0.2 + pasteboard: ^0.2.0 + desktop_drop: ^0.4.1 + device_info_plus: ^4.1.3 + cross_file: ^0.3.3+4 + diff_match_patch: ^0.4.1 dev_dependencies: flutter_lints: ^1.0.0 diff --git a/screenshots/chat.jpg b/screenshots/chat.jpg deleted file mode 100644 index 12bfa304d46b934ca4a237d732c6302162d36705..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50109 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 diff --git a/screenshots/chat.png b/screenshots/chat.png deleted file mode 100644 index b9704cafb428b5e10277135d4425279c38ccd7b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128456 zcmV*HKxn^-P)|F(%9o6+7eZC%dBLW0S(2xWR zuEpK0xJ&;n4n-=I7D`(vP@#er4^C)E0`ZUlNr;EItvwt2f9IZgcPDGG%We|VxxcW? zzI`%p=HBm~^PO|PqrURWD~{uMV%WCL2YAGFT^zW9A)m&7!mqJd3_le`;h%WivMg0q zbzRTr^SNA(|DOz%9SheU~O$}BobM-Zr$?b%keml`Q?UT-~{k;rDa2F(X&0J zeTS;JN;tx?y$r8~>&q-me@}JkP<7>s^9n0l_3GYJ4J=4c{Vwae#p?@@0=xn=B@&4~ zefpG_mji;z%F2?-WKmI3MMVYv6pzONQ@|hk3Z}`g(h37F$Isv+Jn#rVS^i2mrivjy zTORPS8W?yDK$Fi;z6*maza4`t11nIKArgPxxN&23b#*$OuB@z#Mx!gmz;^(i%JX1E z#*p+He)%Pk z6yTFerPi!jlg(xUO+9+_sHv#|-~zH>;o()V2=SAxJ%AWsjiE_Gr-VfORe~7*)nK4( z2&oL0jp98IehYbwf%9flm){zvi!)ohb}deN!-fqwzi+CNKwB38aFlhsS|V0HqEcIsh~QSupzs3>W|)f=!B_ zc)lqHUJGQCNLUYB@#g%i#7X_^v(J{$$tc;72WV)h`n-v0%47ZjK37=L;7K=#0i>Tk zeL4^p&%rUQZX7UYAw7M@Vm4RX+wl)aIKt6>!_j;f-Xj?Gz4@l_RQ%6X#S{1+5Vr8o z6aUn}BlOR0Av`dkNdpnkDcxucU=EB{@R0EO8JB=mfHj~huo4iApLmejfJV7g`4M;~ zBdig$Oyx0~qSAh>yC4m$REfn*E8qawzi81Sj%a=H#TNis9N?Vz%lIDWu1fl9y!D5W@UJ-0Ium8xS-y?REjWCpZGA8+yb6u^`rkB?!)$zVGJ z-JCgdV8HIN#~zzDZ2~m)?c2Asv=q;g24B!P4RWbL>(%E{8#PNA=J;2}PblDNCx0zIQ5GcFUALh?wvh*HjthH9*^J)@CUQM z&yTZND#4oZl(&U&UWOwaKhUB2!0KC?YGX#Ir_}lHLG!c0%CAqS;>kt}O)kbU#vB}Q znkGBVfKlKngDD373On!f&p(F`9TfxYCEfu^S3!?FXr(qpLV~h$&po#u@4yx)hmzRY zmk1rq4ZssXjN&Iw3o(6I&Nzl;igUuRyc+}|Se_OexecM5pCJEQ|7sSj=6Wdy^1P@77a^}88}s$9X3)alwsvo^Tk;9ZgD}q_99!BkFN9^} z>Q+Qph8e>)nCG4zv^nMSgn=o-FZ2)`Qh)>gN5r6`O0VCylf*$(gxYOSq(BwcvVbN> z0-rRn+R#+O`vA&-9y4al7&2r?$BrGp`s%Cx{rh+7)QK+?&YWwPfO0{vTH>-H!%)Fw ze&z@mo*0`rI?p!)#wok)_z6}N9|@3!k&LJmCw9>l5qSx%_?}I@q+V*5vU!$5y%<{1 zZmoCR-d15#5Xo1MW>SDYX4WQL=i%65gQ-Ja;L?y{g05{Ksjgaza-;A$?AilAG~Hu! z&k?$S!AgJ76JYGHYLI-4DeTE~RCywcVBYq_4E`aK6%e)4<5;YL~&P?f`3UAuNw zHjn$uWYD0USC^OCuv{t#TS2#7!U3Qf{ytC@!6+tD+4Rkefe&LAwN17T{PJ4-_KT?f>g)FHNh$B_{Akh2y;TwLnAdDTX10F;U89kp&Nh! z!z2*NTW#ho>7M2aHdIXTx-gUj=yY7zn7XP(QLK*B$mI!-;(l(s=VPzKD- z%*6wmDg0@?tFsw%Ds85=vQjzY6Tx=2+_Bj#Sg-(C$6FCs0f1&j`YOmzMWhM@%}}CD zFSy`>W_;Lsp&mZqd@1<*sE@+uAta@X!B#3PQ+z7U05IPs4uvcx3kI+1!~s;T9y1_q z>J~ZXZD@@)#bL2^&s+@eJw#x6p`jX%EeNTuzoI;!KvbrUCKxFoh>xSr{$QCEq2s-dXJt%vikxlY7Wu<|1+;f|NfQ(aX9 zJZ(cm6-yG}hUgR9aBRgR-VRs;lENcLwH2@q$DA#|fWu}u3!4}XRZ-+IyVbn-B?_>V z6#RYgr;Mi@_5zTDW96t6Q@o6--*fkqRx`7-(w%3}q}m3@3&#DM@&&efU|m|-68FQ{ zR5-T$z>?=6N4?U=wzDY&MJv3)K&2Ca)`1@{X1`}@@e&PJ$v>9NsMEp z;3ByJws%>12b=?7-M0#EBO5|o#n*Wje(bCCal(9<`ImQ0^KdF`szMYTC! zJk+w8v>DD6 zSH!2o31H78TU5Vu-X`Xln^RRK-KsD|+|tz2lBM4jsDd4ub|l=n&tK zs%`@ez&2>*6=(=8utobxUAB`4$!^=$?|%E+zx?HCrnlh-h3h;VZ9fk;_lG#FPu1aO z^1=%*{PB-}%;k$*bmPa4+Gzf}n^_osa2qo}n@f9$C!iudo3nCR__))iOdT_M`bN{M zG&IHXVmVjAA~Btemort@q$n05J|M>;M8GDCja14!`tah4jyUgBSqYwPS-IsaS1nz* za>;_F^FIH4!Pj$aw@QsFIa{@zxTY65&PEY`(;Z4uqGC?RvJpb6BQse$Q1wf^n$kN4 zi18IeW>vRt-MV-0zRNDVz>MPuS=5vfxz0)r<|HvN^R;Gd#e>)lfTXZb!8Je$g|!7a z-<2~n8XdfW5O&aMk;kD4F-2SszdwQ%K!qn!q?Svj!2uoAIqjz0S6 z%PzZ&y;>|lRtaf8(?mcO+ZZA*QvuR3u}abNU3S~GYQ<8oIvuG@V~yuD&y3=K`IM&T zRVRm9DWEAy1-M91HS;;WR$DV}qPg$xcF#^}ODi?wWn{T_96EfDs2S69_L>#TCQP32 z{wE*Jn)8Ldp+>W+jW}g7y@Le0FW5(h2TCyQt)2Kj~~yqTpW**byiJSspR`>Y@PbFil9E}(h1^K zV>tt@NAF(eUwFZ-xBlcuKl;(`yYJ5FU;tmobESxu7ogIE^3~fAmdeSbG@=aQxeiQi zxIrB%D&Bqf9b8o-%u5YN`w&pUJV-WIVW3=d{Y`NAn32O0W`3|01YI-pKM2pBDBKrW zQ8t;ZlvjlYA=D%U252goR1@C%RT~nP3R=L?UCYTQup;sn&N~PHm<%w(Aw$YTs7S{N zS7+8%t*VtJSTyeWVPUmy*-|X6NqH9F57VqLC|9jo1rie16U1XlNeLUOvIvbJwaKd^ z2nDp`z9irl~x!Mw7j^F-Y|azxe?{N_jIW9+*zoR+N{&_~HxH z*FXs)RN-hZ-#@sP@hh0qE3Uqd6Hz%O2vHCj_irCa^~f)!d_gLcf-%8Z1}@ODEm|S* zND>U`idDz~h}n(_KMuYuOem^X)hu1bKbT*p>qV&4%89C;m92pof1KlxLUDX4%VojWi zAElREEgyh305dvx@Zig?yy}LVZro+)t{O23QP`}+WeacLFiby0Mv0tWP_w{Q#Le-j z5O^DeRClxARQ~#esy1yQi9{UR%-FGSuV24G^_+0=hokN1VSvYz2n+l4_>)fM6iaqP zF)gvc+mK6b0I9yirV3k%mVx662>^|)SL9RKiKteZ+_-vmBJaTYMdqrjQ)~;*LVPN( zk)?`cC76P$=BC|zan#JOUGLP?mX(ydW;ACL$mpoef(_=76KsHE@LbTdkyvE#kX;Tw z_>i7Gd#zZta^w1qI2niBf48Mu2uG_Jf4GzhV9NbhV5`Ckly=@`j(^Z=z<0; zp&fu^e#E9GOqjrxrYzsWmY3uQnz*%!ykU5)I3|SzcpT@PbIz?l{n=i7?WG&0?%S}i z?kQSD*GK@jB`yGSyMD=p$j?x}yI#W9fK;z;MyZ7>Dzc_rM@Vxa7easc-FLA+g;r`f z+RyP1iVfi>$}5jK{v@vG#{lodi?VV7vKqajjS7=ca#G;1PvB3)Db47+}t=XW})L6?%HbB!V9H+#P zIr#M3%GJ+Jh(tnsfWDjkTAk#Pz<)2JB0^&D21 z$|`y)k;>*WW=SGZQMzXJ>ZD_67SRN@p`yqt>YyUaafECYUWR1)oZ?!ZRvJk-o6@V+ zuS<06WG7;}t4A&5#CndJb2UOI&5a-!tchfNu&B{kWZx0{4&HIdg82)oswy2<5WC;m zpkXeRNlq?kf>{a2opq`ZumY^H8LNFO4kEP`{yqw&IBJHs=5EqTK_(R`uiQ|usZnUy zhoT7$pMC7H$3FV_ACMCV^aPhGQl=EQ(0EId11y#k6czMTCD=}tYj3x~sq8lK8@@<7 zo8>eK#6Q7sH-Fv25svTa_y^`5R<4N*5=X3PcoVv6nT!Bn3JLaH+|M0}0jyvx7g59$j z0IE#`ENkb>?EzL17B9X7NL56b(8>fRKf{rJ)m2xq{V2O#%Orms!vckHA6^C%m3;(d zb43yvn_`PqR!>P?1D|-M$UiZ-7hZDd4L9CI1y`D{hV3d^Ly-X`(51ERubY=l_)l=X zdaVnj*Asj>gL0$t5b{;^BxCqfWKV^lx?pn-SK~W3?ae%&Kq13(K_2ep&nC~DIm7TH zb^a%EZbP%-zHo%2MZP~39kHc?@b5k&N6XGejass8_~}0J7Z7O`EmR6QvmOVZHBw3e zO1M-WV3rgc$z*j^Wi0C;c#Y>0SiPq2^xYh-j@dg-N7;zVK)BP<{lNm!8Rhdc`21@OwXQjHEyB<64y z3%4*-fs6)o!Ek*0U3WuL02vgp!s$a5&HK*%5a|2RKSheva`A95msW0r^^!t@9j+S1 z#Gr^ly@D~mcDyl2@NJ1T>(%QKYL_con!8;&1{l`5vL zAtM?1dFY{s?lNrmcKuwrF8mxv5lxVi_EZHgaE4S-*qCu#n;P|LCRTHX4V`Y2oxmR&%$@u?{XYUt89P^niU3d6K$SwuoAk7vjvOZC% z6dFOx6ngwbeh-{|lzicsGyJ*Yvl;K6(T8aPDa6NR8_4Xv$V(eB@D=U#j%#Xs`KZ z?2}I`S!?i_rujLFu_t+T8Y9%KI8N=@4EM% zcsyy4W35vPywl?J8@wkV6~KrxePl*aYt<{RxIzLV|KwjW=FgvxDk(VrQdqi~$i7n0 zxng!k%9q$6m}BwlufO56(@*E?Y?0834;f4mfA`%l@adX#EM&?Uca^Ev(NN|&H_9<7 z4LWYsYqb(oEnq-oe!59IUoB)e%Sk3)FWyigYTkE4C`Iq(mtRJBN|yWv`!9xyD&hE^ z_M%)DtbYb75I$mg$Ie^EN|ka;Ql>7@PgJjKv1gJD6|$uez49P8h*@t_Jl=^LMIFjE ztzPS;^JXNLN8(T-*1u1`18%uB-n*N(`kTN0;#Xfyo!)QYppu@w)T-KbljoGxSk;vq zW1Y&YV5$NKNb5S!P}5N5BagiORC3^efoLu;`P0dHi;OTJmFqgK*g_ap5%&jMO$`Fs zx(upPVTHpiMLe4MSIGl>>s!l40*n!y0gI%9Q%*e<4YWxCTc=y=ib4ucEmYTjXS%&0 zSR-ndLB}eaDP$`meGDe5+##g9p#;iUmCgGr1f>FH+N=}_#2d=~w35yE?xiMv|1!0{ zgc=OhF5S9z?%bK*GkAu)b%l@+j_*%pGKtAVVXt1j;25>{=SqcjsmcsNkGz$YHklv= zh4rIHqDB-osz3=ikP*X-M!bl{HXd+frW_IgdK6206E*+3m74u9)u}2?!nA59V z$+<5)_~?eOzmAr~D*ARqs4G`(r-25=$?U2%D?grCk6IgfJlVWRbS^+-3(O8Yi_Plib@%3q`so71rSs{ zNiQ%eNqbp3)RGDH3ws+_tig_E!AO_fWBu|i2Q_V`RQ+nwN-glGh5xH;Gl=u_sT|r8 zqp`2PoIB_98PYxtwgU>e)Np(sV^OXeUXQ?(0}nh9>QlDY&Pr@tgd}A)wL-r*kIG%J z3c!m(IF%Bjm_tLl6i8Ik01^JNt{~4JPtYvIK*S{(Lrs3Js#dE7W_oiL&rR&SQ>SEU z&y1Dm)?xp1PburyPgz?t?)m?ux^_6?rYrS`_Vt{(P^l^^N|A^aTtP^rDBKsYa3U&6 z4d5>ZF%PJuvUeG}%eoEgX3hQ_$(yRuvcg>1=?-2$j$tH`J@&fK}c2Vat3^OrBn61 zk3V{!&3_r_4~f)pe19r6IL|S!;E+Oqs&C)Ej@rJnOXWOB1x~y$L|igT4dDlhKWZc% zMCPi)G@WTvqYIZ3e-s<4)QaeginT%t)LtZ>j3(onsb)vtrE?P}?!K7(gWlc$0iJFY$i6P`FgM!zuYQl)o z3&srsJ=)NryG)xlb=B(CEiJua|DL;=q83za5(Plv1n=d)+R->urX z34iL+r5m(52M^j2Ym;pq>ZYut1~rR$??g1L5G}97JSDFy^S)WW?weI0NAsDgh+$Rf zS#|xYinTS7c}s6wdSl{Aqp&x%aZRxbyNG#E>ONX6y7`%4g zqGjr|qS3p?JF-NyQJ~pd!Mc-F4oVd2okEZ3bYU$khB$XJCLmcbsYp>mN&pk!h3t_iL&a>gKD%X4oyTK;1T-*js zcj#2QZb?P?@h6=0_~Vaz2--Owr+9!<*R_J|B#QA=x!v&Fw9GM4!zkAe3kqAfS<6Iy zGE*Gi*Y-rI61B~9$g@QF`-r2DOO%v(oYmCC`mJYeH0&!Jd_pklD+TT8S1SjTWZb*& zz3{>d@4PdX65tCxSqXYf6Nb)_M;?9dx##xj-w&2dEyPWuF&H&5IItELh_NZVY5cg4 zFmXF}D35e4sjaTUD^q2is|W8oWyZ{2->iZ*wM$NyOuBga$2Vqx%gXY_i)?o(Q~!!7)n{GXO?9$F(j4&3Q$-NVnB0~nx|)S zF|%mYuA|R6?TSA>`GD`RDlA1JBJG}2r=+KB76FoiCpd;sAJD^)ArT-cUn3kKFvaTM zT>mQ*q?#{WBMoUY%1?k$>**BY_u6pR1+wGZViEI|S6;d2uDjN(SzTLG)1`Y4{$e=Q z2OfCf>8GDYwd;QS?FU2kt=C_NI>B?#JqP9i=Ra}cM5Ngscgl&S#U*ScQYWs(4(h`2D?X1hP>q?7*r z?|(xwQKfI8iNY#_=jT>gqT%>q4H;ezZt9ftEf^&1{m{Mxc%5>}Dc@3}vUz{G;BiC6 z_eRl{{oTq9>wopDU%mAF3!64VqeO{BO|DjFQcIX?iy*;{b#&Ib=UjX3wS^>nRkDuo zGT|Bb?bqj-KR@-&@})4Lko<^DtXwXGMY?e9Y8C0G7G(bn2)oV5RerQ)0hCoC9hj}I zTKo0l>NRUe?6k}3O`8TBu=A`X3%b2Gz5hWew=+`ubsH>0ap@Y*j++sa>@13;Wk9(` zAbxE{N{UZ7>%@27|2K;7MSNK08Z)Z2$A-#Uil)_uU-$zLRno3F4 zuey@ZZ?jShYOLzXC!Y*YIg`$Uj&7@|lR(awuCH0W3Pxo-8ol}ETONAoL8Xu$k7TdE z|NZYk&qp796oT9MB9LYI@cs9nefC*Yh~d}UZ@+!!v}u*;nyatA8fI)F8Ut_h@WT&( z_St8kncjT!O&IB#u*xwJA!b^&Ztd9@Uij<#9sq}3ldi=#n)KRQ>wruJB_ur4#UUls)f-TepK|#V)YuBzuCDNb&{O7+t{fuzRQQuGfTph9E zfF`Ce6!8nf^Y*&s>WnFzP)RMR4Q;)}sz!Z91F9D|mToMuvC#Zz?VQitxgD*&jvs)m(M+lr&XxpC9L!w*0F zwKv{4?6AY|wX^ATOcWq|_~D1?nwow0-52cuI6j6DC&zxvw4$?FgkgX}{5TV5w!l-QWaf0G#!zZa z1?G>f6N!dJ5=EmWgtHVi=eg;G((`~3gZ3W@5xu>3*k$NJqiZWG7fqg$UAwY2y%7-- zWn(6We;ITLL{kyV&3O=R)uS;|2h3C+ee|&)d{rTZhih0UZqfo_okp&k48x#2%1 z6uQ2ENKxm{{R+3ZXRjU>xJZMT-@W$U69=o;tXi{nHL`FYee8Gm!l}|yQjW+|`YP;M zn5)-ce|>p*8TLuMM3&XUQ36p5mpl=Pp@$$kZcUgp>GZSC!URP$EN8bFq@o%b`^0tE zT?c$$v23{~nm2%BqTMg_*~9UzHltGry26XmwStpQ0d1`59=*F?d(CxXVn?|6ul>sT z*+~WYhAv0@AFv;m>K%97@x~i(z>$ZJiJ%Q5JMFa7X{Vib{`u$cvBw^(R<1@lW!{zj zmQJiX#ygyP_v0jljK-mEtjqqbbnkj01T+Y4(;~^4*VqH2R{`2A3549DW z1{||bAA9J+Y13DHGP&1*38&aFVhDo4I*Gb*=wMk;sDg~3o6Scx4_#XFk;s{6o_)t1 zw{Z+fwo3Ktch&NJe-1K9)00B+k_%v91rEaT2NB7cy7H3M>jl^dGytScg5Z8T3^?SF zLty8}lZnl%0hbUwHn(2af^e%0*u+(u23^+oumI6fh_L^rt@we%jk> z#0WSw_$x{An?{>>{TSGFVu^UqUcK+S^X?mOx&b1L;$AX+kDfP7OE$7-?3XaZ>ToPlQ#7Pr9nrQXgmgs3NQ-j{Cvg?0kveq;ly&; z?6jFPrcIx=aLHnvn7)T@yN)02@%;AAI7?cpA_Ir004zz{#u`zDKSy?+XXfxKsYFVT{~*T@Fn9WCNq_5-<{ZH)IQanm25PT z$i(B35-W#DG$dGs5QzqE)w4Ahk(hq{2F#v4iwwA2M(QOsG*Lxo(z=p&rc;ez=@AZK zqQY=P=8z0qNiYp+_%|HcY~B!w0b|CDDJv~US%L_=N9;E0X~Vg7+{oH6jjR}&06|!w z61&+e#|{U>uavL z2H~k0vu6F{AOAS(th4_7^i#-uQd?3$^=*p*fi;|yGjjB(n{K}4SHJuP&dm~84Wj#b z171AD+3k9?*oM^nwn+s-lfVV8TP&IS=}&(;Z1>^Rewg%#!Bm=1w~I6pR+S8CLsB*9 z+6SLdPdcs;C|5|dF9CxpWkjQB&V1BSMjg6ADcNbEpj;ut-$Fh&%=ZjE6(H`q&&Sg>+99lRB{|5P;2CrHVf1t#Q@;d!Kgx zIn(-e>l2Nx`)0KoNp>x+SnA@5T$L|Pb5Io89P1tn67e-R~YZ#@QhMRHXVV zZH1>YvKA3CSG1!P%HeT7+z1N_+j!cN<;y4*?~$xEO21%qqh&cJ7@mXR6(atZT>4`) zUd65beEQ5?hVS;*zy1|gEeucYU+~aF5AA=@ful!{e(bTw@RHkayX~}-Per@1lSIJu zPfz>_T)~r1K1oTen%O4biz^7MJoVLqk}O!HyYIRaRL3Y&L@^ z@$die_y_O3f9h$c0A66Cp-VGDAmGy`e>MdH-a-z$=?ZI!Qo(HGyz91SOR-RZlV>9g zY)j^kf=Z$vs0;lzom^K^r$e4*-sNsY$j!_loaNXXSFN^HcaveSes|W4#f$pwvh)7u zU9jT)cgMc<>Y9%;T}JJzbnLUvHj04!N+O5!OcT^BTC2n|b{b%E;K5_C%(L0F@Q>AR zEfALoNe(f0Jpr0XEFbp>g4&>b<`7)l&XR|PI&OY}Xg!pf~ z{)WX%7UAWG9&*_I4?b}EnP&*cmpXJPg%TLxDML*`ddWc;S(x0M%kHvYNZqTrV?EU% z3R43LDV`D+xRG@!4M2$~Cth#{3YI!XqPRTHLNqtIq@bY>Ubz_F@8MNgD+hTBo#K z3sg}`-+lNV`;HuqHm>*FeeXpVUG%{RAH4qB8yz}zIqAfcYirWQC8b9nb1ZJ~$dMy) zddDAsJaRkeUgn5|MgcB(QvCXxM;-=)j#~~?9sA~+Fj}v?;wsdcq0jcep8GdW1Fxdy zy|H9NnwUYZrS>FqxP1L1Cbd_CmvryF_xWbJ|lFaF^V>DtPEU3&mjmw)_8_faEi zqh6&OD{)hCGo{Ckjk$C*qH{_>=?G4-R5KH_RfoF2Xjpp#1H=R7gS588Vw6ZTL-CpVw@Dra$jPdkbnfFEXjZ#k5f3dBo92oqFo2{rV3OKxsC`xk+IoPDtl) zE0#Q$y1?*+hsQ=MeuX9g?9drAW-wy*@82J*1C%J9j70%E6rUR`qvE&=e+ul`9DG4d zdGEdVundvH2+|DiCMew;pq9x-j;a&Qs0f6$Y`i&^A>J0*smXYvHk0Ncif^8y{dC?& zc9EB(q@5Z&SDnwQ*<5bnHydZnHLGg!s=YG3p`vp|mt;}rSkd9Xc(ACXMET;Y*B^U) z$P5zDjv0m*Ry*}OLdGCp%s8q8cXTa&?S|K176NN{WO7% zZi~n_71kW@SJ;d2F5||HgP~Wy9^*SeDt->xdFV4w{{`#>_dYSB#9+2qhM+#AYJn-` z@ZF+_lby$1fAPf^K|UUH%rSmDRm*~d4_L=f+^Q2#JP|pn{9W)@N&OZr&%RpfTK>Dt0)w3p@=9>u_c?;IDW8fiNr(!06V!hcF#L zis{WnROIfKy2Hr*~%7+6yr#f95 z0d56qP-g3vL zMT>gwwacOZcb!s{a%O+|?1K+yt25EQy*ll)Z?tUNmUwf8CpRHmc$7}B^8)=YH!yy8z3xADwZzd3$ z;-jg#t<}l_7CLvs7u>7$5PNC12?KDEC7g<38b7 zDYPII!nY3aKRE(q-0Fi5__-Z;-WWRNQO*RwPm1+-O!Bqx?EIj zrqQn83Y~4615>dm5=KCG_a87|@Q@+6SDYxutEgVnmvH>x!&6P%N8E016D^hAC^s9>L-$xKxT%2|5ub zk3klj;nE_py@-bhJM;ogN7pJ9OEWw6I&yUNC)1UsD~i>~{HfEsd_A}4ZbPqr@NTDD zxmVGtYTEqwe*c%a7Cq$DQ(;Xx^HTJ#O}8NY+%{g1cpDI!Ud~}SBS29E6C{jQmPUmk z$+mbWI)3Ad4WKGY_2^~0L>WT=JUC2WcpN@{v;YMbiidZo$SiNT#XV}1vUe;c@R^3$d>F=L7?5wjALx#Y9-ZXjM zKOTQ_(2#*+E3$-A-o{F;^tU>Tm@LE#igtz2XK_ z5}Ptt4Y?p$DV3eyR_JwtSiu<-s#o=V4z?k0R;{&48#vLl#bq=83{ZvVVmq=A1UK52 zz6pCVe&qv7El@9uCWr`{Q)#a+R|tfn7o${3#L(FF5SDM06;uh{RNrvmN!Fl2Zeq5TgQVW$Wm0;bJ z#9z`Q6_1!^%*thzK+Y!C7cZ{7sGaAU8k`FWZ$@Lxr3&?8pOhe3LPUqe3FHM?Cy*UA z?nv!NuXfc|^$e;>4MeQ$q~ez3)EpE*V~XCtM=Gwbd}l(mDqB5u_8(U~R61a%PF8B! zl-UFJ9x~>Zi)uAx0p88VGPr-#BRA23@4d|2Z;m6Lk8h-!JJrk7}GQ}?1?uX6XW;*Vy}I`E4b>9uRC)=bPfDN8Z;K5#$8 zx6-p`jlJ);+S;n(&%fU1+Dp3ZJ$%DQA9Y>2tjh}gkl-IdSmz{UsrLwF{DK09GB_cTpuUI7=OJGL6_1|%7 zMcJ9xU$r7rspNAh+bglvTy4#|+NuSg&B(4=tJh@IOcuefPF*?z_$}1L65l`)1mGM< zd(|zpLT>1HazGpc{=im5kV%}X&<>tqZ_r4W`*qNTAIDr2G=DIdqo zzJvShyPwvjLq4kHYbz(e{kF1Z<1xqn=;VveS4xXY2KA3;?RlR}Lcc(CC_>n)EMsXa z*DV+~-dMlE+qj`58Mh55t3y=;YD=!pCMy3E>Gus!kd+EG&grcdgHzR7`b|-4R<8y* zOzR0pIKt7kBf#Oh)Ii!tRfR>Mk-JIMtZ7gsYy!1c2_;riG+;oN(R*zuk44Io>93c) z_0aEXXML4Q7Ab4jPXFgipT70JNnvWuhO8CD=F=JE{djBEF8uFAXXUDt;-HifjjJ3X z>`#`dR~JcYH0j%5;N!p)lcARS|{aJG|kk}$FEj%^#Of5y7q=oCP!CpwB{{&=BC>sJ-VX&GE$Q*bt8(E zMJzayJOP(vezQy*bf&RSr_RVpj6RG|Z95JM0xj#z0g zmsjHh29(*ZHT6qp*~)INlKEy05WlhzdG-L?i70BkDSqnad^=!&DIPt0;4XU1^BHqAx8qRFO35N3_(s9yQ2Hcfy!| zIKmN*wl!2W$_VwN|14A*i{`VwG8X&(l-{W-Y1d9cr>@e=B-F^j!AMf9%GM?~R7P`| z4k$UZAr$}$)gZ|L(ODpk$}E6$t~PF@jC3A3w9wo{4goT?(4rcBS@926s!QR1tx;-| zFcgVX2=pU0m8C#9(YK{cC`u!IWrsrb1=+bRR`v@=IKmN*=FQa27y!26DAx!?swk}| zDSm|_R#EEToFvs>Hmcr}yof zGPI>rr=&L4B-T_%JuMH@GYZ+|T#=WsMMa`bLe~}v>`^x=Xa{HjUouPmS`4mC)m*ia z#zh8~19Lq-%NlWdX-lnCmTvO#R4vq3h~sdCBOKvqzd>2|6#n-uIz>@szG~71Uy4|j z9W%|6Y!V_G=uYLuA{|V1&4kb5Sy!vcpfPINcA`eo&A1UYXK7TS2wN3hTP*Z$F?6&= zLI+Xm6Ne-!*VA2zY7NWg6+=ia2!#WoLB&cit*D*?q;B>l!wjl$gd-eV9$rJn|J&RF27$f=GV)IH#r>P2uGWZ z#-)ij&#Wp)3Lx+#)H%_OS_KoTpb9{Z=JjYETB%yLNAIqqthFCcD&3SevuKv5Knpo3 z1h!!JIwTB2g;I>8)VM@^INQP^+n-p7Mr2bsfmDdy<)n(U)R<`zq&BQ!r8fy9{^1Bm zINE4P2vfa)(=C#jC|sm)ze1O_*F9o7T|-wRdL)N@Q#YB?kxXK=BOI_E)>JH=Q+Op!w1#8bw#^A9wrxzziEZ1qy_1P;+qN}HCbrN1&pB6p)%A2$SFOT& zzpv8Rw5vyiXQVI>=3F=SN}}+?J_hT>HM2LP9$&Y^H&xX2nAMQ1Cj(2$BWWxGw8&+)D5gzIBnuTm@H)W(2%D3-j*Fbjf6UEO(9GuS*2ThU8!d?0%nD7+sxxYW zel2%pMWl-NSDp+Ja+#~H5vw$$34_wpz3z(VAQsi$xkOG-h@E-cRQ~#y;OCZ`V#g3@o~j?0u*73AGqx-9Kfcup~X0vAg;DX zcaI=Qki(P-BXLXx!Hpt2hTu}|S3m>4K;;oLYojn!x7h)SNlZRIOYe<6)=o=x;*Dhz z&ROZ}D5`U!((&gKL~tN4fW|grVY-P%J>}6-E*7y^FRA~+1v$ayD%C|KTe-+j+*m~U zVYT8okzx6H4+LZ$m|ICcccuIu%=yqm>a=pbQm9xEvY|rj0(`M+t8jJ|am3Vfu5ddD zm0$-Vyz>8kW=r-wi9ssw>TkGK&B705sR9!46lF}Zl~hNrq^O71oT<^pyH}Z^X0d#E zO^}MeNTZj%d_}6Lm27yfAHn&A|MxkGr`K3Ysm_%&%Wyv2UZ~MmV|E8E;_2}Hbl zRbJ5Iy9odh^4>q03L}TXlf|$8{Fus8lM^?jksey{#rm-W=~IzrQ)%K#x&em)+p%w8 zH4F*)WBfzXoHQ62 z`#w8P_hOIR{^lU2yvhE|2>M%8s>`IC_8Ik-BJ;9`;$gV%XaF0!Wyf$(3PQw3+SzAi zzFnEp_99Lles$!NmNm`e_PA~^=&i%7a&nAn(`>A)IAgakKKty$KdVE1g!}mY4kSjF zy6aoW%D8hqWM85Vc7KVV8PA1(Z4)cY+1u$I}Fdc&OLWw^@h)+0$WV7VX% zQfHcC^B8yv^NK|X7_YUcQiyNwx=w~r_jbsLHgaNDgQ@7j)C9FCF&SED`+*qv1(U>{I3$D2D5Y z4<9J8$W;{s9Adv+}OfL z844s*5td0|4%vGrnwwJuhIp|WK&OGp!;wZKsONd3F?<|*CIS^1p4Psm8(>XrAjJ%g zBnQGax^emg7CR>}^_l0Xp|!adgl{;fUvY$c2Lz|OB)=v)E%Sxx1zjk)7yEkGrgXwx zwAK|iWy>R$6?ODq@4XrY4A!?^0xYm?D2PIL%D@-7vK8>j>_s;QX>;+}FYbhZV>VevA+(AUKtLm)_~0?yA-@`4CJvffF@1&uAssM^3KRqr7H zQKK5x>|+#8hT5>%I!^Gi!d|xfTWf5=-8y=1dj1|O)fbm- zkWe=m$x3PtlY7Dhd$5@s)_l;=P#Q2BM(5UK zSpAA!5U`vcV${dnOQUNZ6e3aCOh_t`INfl}!rg7ZCFgYpC-#X;dA$_K0*53V;I;oK zeqahZw6lh;z3<6ji!@XR&Io%TRV==6*_XiyNj?f~$zvTG0uW zwhzY#%VEm+$HED4T)o(XzU3&RH6msU3LrTnoq`mDN52A-rH_rX0+TDyqqSplFcza& zg6`#6qchL_T-i76HI+I|Txrazjnv|8YCISgv?l zJECcFxzYTBu3N_UdP|R=x~9g0|NSy5Sj4mGece6!kM0*d$EiLs^g{n=?UJSf0-u2G z21gh5J$P-;+xfrs##cm9de>|`ia;{n`$R4TdCZW9c^njiDrx=V!hAT|-|8>#aIN~7 z%C%*N8%ixINrK_!+{S%jbSIQ<*Wo}6583|(94DZmp&=Mq0A~>o84DY`(E>Z}hvRFu zbdt$k3OJh&$$Fn{EW8N^ghtQz*L&~hrM-Rk<4PjAWRdS%wtWw6tF7Cn_v86vG4W>v z{}prZ$6aMr4e#HAU?Tqy#}7>Q%l6Ye@0)&TMZwPpVqo2D@?=MecL{3;(9Nf_LSbJQ z^S>UtoM-+M9f!1JH<->J03kENS!nyd8^r7a@8>HZ**D9jZadWJ`?##h-222!B>cXg z|8Ye9H~SR`Zb4r!!tozCG(ji*Xd-uo-#NPi{S^ng{JzZ|Kvv)c<@C8=xGuUuGEFCJo8lEkb#tINm z5`7LjO8VVr@AhSN{w<0IiapwF*>eW=<>g{L?@y+4c<%2enMZkQwR#@DystS;Sj~@a zSLJLkBNEAx`EL4v#20=>=c2+-b#?W6@o@;SI8e{$9bc|EpfiP+x!`d#m`pr`v6Yuc%z`^qJ(w%g&vkv>C64b!Yh6C#BI-cyWd~WB==C4ZHKk~_ct}2NU2X4 zY>xVoFxl4#M(2;MHu`H0;_-Tg{jyEORHH+Y=*)cId?fJ2hhx3hjvjX7qs zIlN{QC6SUuel&ljnhm>E-twfzOx#ktbg04O@&|;|5LJk;5ejfQOdVELD`awd`K6z5br=cLLWXO@MpP`u-`S2!)V~QNWA)> z1^1iRG5S3|uZ1Q^0;W^Ky)VPe0qv=r%Z7UaGyjP&|7*C&!=2rxlc?Dde}sm|BlNh* z^53XRZV)_sKUz3M3O>_()i}A=gU4MaT_FOK(>?qDF^!d&$ZML~q^oW za;Qy82kN-8Wq`V=xeqm3Nf<9!GC^Z0l~#7@9LDuFa6YKqB90d`(+!mNyZh}0LKD4j zU*G&K$aM!x?*I-qx=X@@4K`REf;o;_0LTt2A zGoVJI8*xM;DL2{>xgr+WWHxx3%Vsvg|GW(^q%6-j2{KTl)$)-f%LM8d82xXn8+!+> zF*li?Mbd0IoCTSmU4+#!F0$SrKEAk#y8iY(%z_F$k1Jo?Weg4VsmsG3F_Bn^_}6l& zEH?M{b=N&oj>}B#!Gp!q-`As8SkmuxtyMN zY6+V0e0O6n-+oSuj9ijr^(^s~kLKE>4vglZlO7YSASY;)%~H;5kKE6}%-s8tmrYd+ zJ@w0fsO$3`hOp#Tt^>-mR)FGtn@1pW-e+_26_5jA5;@dYpnV>S^PXGlQXIyoa><*P z`uV>54V5|ej&)i;xZ6+OcBI!mT2E+~J2_H(`t1L(xDi;6VOt)=pT6xtFB^Qye}lmy z$*jpqpo$`-N&$^W{ilgLkNiEy`(TAV4~)2Yfapj)5&f2iFZ@QWglz7fkUDo-Y8e_L3fly9TWhBWU)6Z8@LmC8Nhjo_k3@hcY)9+aGv0i#4Jg^)S{%M42jI@ zF&YfBp$d+N`qz;aIO<9K*8Bb5J4@v+bDBBX`>`Mkj2KKk4g*?M~=xyWkq(ZT9vh2{R{8hRZ6x z-gjr^bDwDS{(VZsWpNlCOfvU&IqZvcJ?h$bwOh^?0qdLVHFBoNe|z+Dd&pIzn@&SF zumel~P?D@LP@}D)rl#GF+IBxdUptle$dll{YSc*x%oztmA<9sxoY`R2#R(lZh{M;m zpJaXeu@SvwjB6Wi{&f5I_wNwM4PT&k5N(t7unadB$j=@88}!bGBXrAgo*(|IEsC!= zT9NYNRKkawmq5nYP?nZ)b%`e(WIqb1Tkt<$0x0r7Vhrd>Fo2c?{XiD|`So&$%($Va9{umH+o&6RFK$->9_#rp|xHs^K`+=TTol<6?=FE#wS$wsirg(EMWx7z`wf{X4m&=+|-)b_hG*L`vU_l zqr>e23=1ak9Xrqa>kFFrKa$gd4s{S@r&>qhmbh!qE!VUmLfuwoR~CTt4N`MY_j?mEy%}E%aeZpq2FRWspDMbGMpW{b{+UvCxY2 zbd38tAP^UgKNcEka6z7C)-Cd5m+;%}?YrJKa4m8IAuxSZ?StW>NKh5;IQ2TcAhTP$ z-ybQ3-1(IyQ0ws-Y+ARyyKIny$A!vNjZU2(@rt6`#>mLo8DT&@WW*4S;u4AATC}2N z*vCqZnCkiO#bT>HTm#BkMEgV@@i|~tptqRz?cZdWa>jt3N&1Zr0?o%eCmu1JrnR(L z3<;-Ao-&sd@=}5<(~#H$b$1}FLn@^7dFQu!WoCgced#9g0(dzmL$K%xr7q`yaw-)u z+JFV^CPPw{6qfA3nBikgGc(GUDIgPmb35vH?KNXh@}a~_O=u?t1@xOvrpSir}_k#78olv!{G znNL2IKO#f;fSQCUUW-73P-@40H14=kl>)ghG@LlZePq!P!-QPefgyKNrA`2CkPYg^ z{1SoSwO8<+3#ZP5zCdsW-4lcI*vw;jBo^Oj`9PLY`+-vdJnf$-GJnXk;9G{t`}6f~ z3M%?YSx@xuDhv?RO|*#(pfVY1I_iP(0XTd(+a-=v)k4sN$aMFmq^sXRoHD;rwfX&`pvMib zdqm@jm|k6ruG|hde^{I`B+iGWBKUrq-zCM35TEH5S&F#W!W0Gzg4=UPF?!}>lOKZ< zO?FApz{G@@%L?mUDV9XGW+}8H<()W5aqbL}LBbyv zM}L*s%N01=Vq_MzAV9`L2~3kQ-$K_*gW3Pn3*9!US7~&=KW*A15B!1pXeU^8-PR9B zmYjm~58@<@9G#;Ic6PlTi^8M_HXh}aA_Wx5GH5{b?}c_`$d7GF9%4*@n9Lh9LV7blQeC+{NL|@!E3C*^30c>XM z0V+wv$U~{^c$24}=$Th>iSymjxR7xluH1lF3JuE*0*iukrjA(J4a5jglzomFK0re( z3(<2!U(TN0QBfF`G>fD*Ogo*)vxue4z@%Of_WM9xu5Ka|YbmjBd=ZEskA_9O z-s{%xz9-B1`|~*-*LjTRG(TK*+hn#I=Gb+&4_R{37Gg`FXx=f=@$kdib$?*u2Ez_G z>8qlwll;3|aJGCRBb_Vv{kzf{FKk|iJCF(8LSiKC!3XkH7MT0$J3^zY`%sL0|J^UMZO@CQO|jVvVf7?$Uc9^5{Z21Z3D_ zB)DuhD29nBF9%V>3NocDvZm`%5hKK6(aC$5*jf{abyf<4w3JCx2O_4t*@^ZW_%kKN zH^V##M(fC+5pZsRTDm?M-u)2tzM2EN{aRBe6$woQ@oKg|F$wy>;cggrB`ytj)vpG*^x(yB;p1G zi_BtY&IS9-uS-J|?%UfFDio*HP%Lp=)SX~@vg7gZuV25IZbHev(pU~y;Efc3(%xOY29dwk&g-X8L4&-+&m{5gdjP2%Bj^2dMr8;`$CN7GlTszPDGMU zMDH5ZH1L_h1FI-0YKZNvc!xJfxByfbN;j!b2P}8$rYB2&I zB+uBC%MMZ=c6Ru7ZLHb+M~8TsM=BSlLgG~9VpgK?Q-KnSHNmP?ep_6PN_ z8_s+HVOOiBy2hPazd_Y-K&t`?W;B>FMqq#(2FjJ?k)x_9mLBLI9n)^5BKjpQno#gS zD()pMH1cPBLU!7B9ASzaoQ0UNmAOL2NZcZ4jG&$5EJ%Q-krUgw5iDs{>N2z;UliOQHYLLW5xqv?ypG0L_j0x;eOw z%vnIz{Q_d3LLHb5goUMd!~fRDi^yi(gnkAHKwP>d> zxW0N{woEHwNZU}!CBq>B)g{$1TuOG4XCQHU&5R-1iEv4#D5{YBp(Ug{sTV(-2(3+7 z&mC1Pr|04zi&VgJ)1$UJHgnpmxatB2X$Mt6VO^&mSIP5FFFfxJtAfTXnB$K(Za6g5 zV5wCvpic8Aj7h2FVA&dao}*yl_8_<$?thU;lTVcnl#i0Pscv_=4%Wgfl2_znXS^Ro zGmBVBqaty$q>ENKq}_7ZB&3PDGQ6Zt93{iH>?JfuDb@m{M-Ruz<9N~R@8T`K+Yho+ zdFoCoRrJ-JH)ri6=bj$9cKfEp+VW-t?+w?S(>-L+l$x#F%5P8;$U$o1N<{gvRbfbA zik-$1NTrg!?#8K6%lb6e?0Y|N+K$|g~%@evq|0tkI1SkPihx}uABFz|)0ce=3| zv;x3=KL67Jk}_!ZN1P$ATa}x{^J6J)S^(vOYbMAEP;1Bz8WB-?9`oWA*+K0P`2M4X zqKRgqN;qu91x08IlPln98OS!~_4lAQkTqmg@fRiSED)(zFVwtZo;M>IOor|uS_N+K z&&j|FWBXII__iZ${vcXlVJE&vIKq(4-*(%yHLU{LrmZ@k?)VJGjztO!(|LX>%%IFK zCn(rH3dIq5*H)t3LC6@U56H(;CWlagmE0Yyz~?OuuEfIx7~Pq{i3=cU1U!8RI_EgP8uBqN)H&WP}TXmCmfqb}}dWy!$Q0_7|=U+Db6`2sFtH zh0T|R_l7%?pXF#!}tBE)Qa2^E(fFs^)7!86Kt}tz$h&EYN$%7VnPVv-{BvL zv|CB_izeD+=<7Cg77R$hOOV4x!V$6?*amBbeBWfE_fOxEQ<#hWY!MJhPZM$=ru=WM zzAXlZ{(fb65tG@J4H57KJh;PBKycNQ5|ca%il!2!FLVuF#&dkkFtSLG(6)*4sPfBZ zZcfmLwv&hjXbxiHH6>{PrKN#tNqUGnzi_%G!q0-NhVb~TI75> zC47YwWzFpoe!Xp3oN{7jHi+tyV#*g1->!kYigm@ZrB%z)&6Y{93vZ28h!>$s8714E zL#%3iQ$Xsz>#Eob3cmVBJD5S?Lre=q3MdgdX*IkXGY!ypd-6PWJzK$C&t(_L7mu+` zLEGMsCh%D^dU=>FlLMMz6C#0l`uiM=-_HmVHzL7Auz|`A$O88`t?>eB7{N8AxE`ee`tXbQdg%H+Rid8l>%*sJ}8w6Xt_4Bm4MqIHa&h#8LYdbHLSyqW;p? zC3)x;F3gVnWFx-86%9l36?0G;yU61IjU@o47TW7UPb-i6n+yv?<19a`& zAz{*oYQ&xmSxY5POL};1(}#rCH_OIaXCftFBqRYe2?_F^tn);ZuR+L-h_72FTn=Y6 zT5D?m3|39Yxz1#UXBv27S2HW*>Y+Y|VV$&ZKgRlFVR}FPekYs3PErYlL@*UeE3;=R zf@3?s=g`tCzra))T)E>oN?30diK7e~-Yy+Mk!n1w$W#EuGv=Qp*#9<24}D;$G62HB z$n-T|Kf2>JIy)gFBOEMpPEbN&h^HW-F3;JYZ&i1hFnj#`)6gFTUF21J^J1+&=#(Sx z;~x4-G6gM+Q~)gUxd4XbaY$Q!k0#&$OPpR4-hmp|M_-mINkoujvfi5t;*Z|dr~7X3 zyzhiG^}g>6@3Rd`R-e}%;etY9k;jhb={~huv7t%N*V_d*YZpZRFe{BLM&$uW8XMb) zQNZDwp3m(tzn7aN92|pz9!dh#%baqtL_dfm=#aQz4}`@PoM(}qaALr{DKG$%tWj{k z##}=Ai4d+1`+FlD-`mA*r*xkCi_` zq@TaISbGc8Nq#sU?vIi}B5yvXweKdqkNO;^&=L%$fs#XIgHeN@Td&n^YqRmYyzBC3 zh}>~GZ<_Z;VqSa7o`z7{eEs`AsKuBF|Mv?aqb!mdy|@~F8nw#@c#gGaOs5Nz?m{bV zwrI+CvQVNwkW5rYX?*oD^T#CiJwqnJ>JN_cUYv^M&oDV~%0d$5NP(<_7t`M?<8dZ9 z&h-)bP5}ejSIh&XRK^jZ9K>J9L1?d=d(yX5Fw(-a7{7j$ww*Xd$QMdo|0kT!A>^=> zh#8FI23u*$zoRrZu46L7K5V+3p;<0ZqFc1E$y^x)1SJexiJ6S!+qDHUMbj>r7gHgC z`OsK`DuDu{^SYwnlPZB!1LfaXz!oDbp5vfO-*q@Xf%qv;Ob&@0q#?~uXui$Y3Dujv zISMTL1ND;a>t++jAEJWIL>I&|fakc{xw(2o$6?>$m3q{Vi|ATC0jz;)fodVx zX+{Z)DSZkk5igaKOncD!Ux+^BjD)+3^sf%V`tgsRj*i>kU3hIL+>mePUNtMO2`TzyJlf@t>c$*rBj zoqag?xYJ7{j2s?j>V1OgW=T_NkSUe-jixS zcf-!YaPZUTV#jH{Ful968tHcbrC%H1G&5#}PSH?8KcZf}i>`v-9 z(O!@Y>Naj87w@lhyS6)PU>*QwBi9*@P-T?Di!rY}`2(s(i&~iYmTwXzR^bJ4O0Z3P zggt^=ETn8*es4$hL@wFxM~6NWtg|JV(; z1iTSqpj|qUBWP0j-=|4-$dYY|9o_!|VlC+OoEiE55o`a!L6jw7|BoEl+LQt-{9h40 z-vvkjn&+cmV1MAIs`aubYF0zA=wvTMsh01Bah*15X5tso3t(hNYRN0V2C6;;xw)sc z=~(L7hpI=~2=QB&56h)XEtnnxWH{VMO5u1@^8oigCX@z=0@rX>vR^c*=A>_+2jnDs z@4b}J`#;8V~&8LvA{hLD#Mi` zPCuyJ!Fe7Bekoe-X>y>7)(7{qiz#z1PSXY|kR6QMp7EYyHYJ5D0WRk`>*q8PRijM5 z0n;$%sOO=sD)9$u9wJRTd9FqC)`bli<#N5RD)YkoYPJ2qWHbwSH^n?H%stNML_1MR zc2m>T)-fAsyhWFV(jh`G3G-0;_i*>doYsckQtvz(S`fE(;i44VzYOd-{C-d!M4F;Q zn5FA^FZm_nVk6`xslUyZPW|!|R`v5oD(dsTymKs)CWg0`HNU^J8>g$Uy{%(RUTRx@ zsQ&eleAifM@aPojy^0XtjL&UVQ*0!pd!IRF+u{iP*~^L*{RP{z7fo)5zi)zWad7LU zsULfV8Vo9Ur5uc&h4~`(fIhle^q!|e{}x4Gq+e`sa}q_;Uei3EiV70(BQ?+VTp3YI zhK>sfuj*hZ1eV4|Fi`)1+O%A~m1MBC0SjUufEF@uepG=N@meg*!`U%*oCdVwN1_BC zyIA(rQLKHA3sSDZ)SS{3@nl^H7Us!_bAOeGk!NYDnvgK;c?b zR~!Pw@uLg)4e+QitF^1xn%gusmlvYG8suTh{nd*vn zOVV`psP<=%YwLNs^!c8Zrq9({ z4*9*aviC7gwz(^_mn8vo%8cs1()M7^c^6@J)8E4H)hj$v?$U6tf7S0MhXBvTb4mftYgMxR~#0gyYdX7 zf-c3R;eUcXO_Wa$O3mc~H@`N42UDMxwiQ#Z=y+zDdZ0e5_ZvE#s?5e!08#CjX997k z;m0Rja7CMCxG5Ra7G8H5uWq{);a2f*bo!pv7AYn>w9;m=g@Gs+U#uAo2USa*t7@$f zx218G6{JM!A5_YRsIio2D&sb_+)kJLhqDwlWh>wgsH$pl?^&Zpi_>e#Z@7rvjxWtH zN^zB}2+`vfm=;CmbC6>LxLm9hmz3CiyugaO?+&t%&ueXA_;4vVbkB?3HqLb@hD zo8`C({ba>*y{AwdvJ$0=OgtUwddRHpFv!zqUVS<)U@7MDGj`$@?mRkhm-j!_N{qqZ zA1)S~O%Te>j+5%!PEYEo(c93&#Z)EbNGOemUP3!?x<0FV7^^r$3s;2cYG}>tERQSe z#c1)r86DSPd&TcHAN<3^%b<@zIn|NNU%vPHFl17(MopI3QxVD1te@U@m((Z^=A}a7 zOw1@f@PIiI3;quG;rrEEgZOnly_A1z``_!{=ro-*cXBS*zF|Mr0UWc9rqXGQ`>2~Z z!MMf_IAGiINmnJJBngov2DL8eU|o-BQd;sFzkc0ycz3&aB&1V?q(fjuf%Zv|Mt~RI^&q< zBP|!mB-vJPBvCI&R)PSa^xUWETaStN;SpDzruo^3aEPW;XBa4_k9945wJQQz$52jO^90;8n%S^b z|jedxCQ8qQ>zcPe9GB*Da>iU}--8OyTcXm>936P)S?CUFYCvxgDK91oNQ6|N-0 zfI!G0VFCsh^58r~2Q7{|ZDQwLZQ??r9hrhe6il5$B|2RSjO-Xxhu6wmNy<2*Otb#X zQ#!e4>}|5VMUi^(q;T9`?_`&5yP?w$2V6aG7Qx*j4E-j-N%V*R7N%xM8wODvvc zp5=27*ATjjbJvdWVONMh^*3?u-51XSFP;9kf&!0;@jfLQ_9}W=U)KXP6;~1EL}55* zIK4=a5`l(clbiw7ZIT;$bpT#|h!$f;7_oif5@t?GM$p?>hbX%^@$3m$k-IB^A?R}f z_kkj*OF0LA6g-W8X`2^3ptGT(%6pasp(VNhR%zsLtUu|N!lL{+1|KyM%69?w(x=0a zDk}yFKG?(b#WIf&Bmgc34mOv|U6|2s4@`%}AC(AZe^~i*FK|$r8b5>6!n7^96msF? zw?^&7HTf)U!JKt~nBd2>h-?Dquf=yd9K6Vhrbgn$BgEXESA z9u~`yYK~c*Pv1s!fSLY3|x7G;OE6-dh= zQ>t@)qM)iWdSXW9qV3zjfmpl*vG1*CQ=u7o_y(lHyl?h|hu-%d4=E&?Kx!`DT&qw( z`^-t|a?bjQ9HQJ`tovQ%6td4(1P=~aMzAk4**%u?+Mu-1xM^oCTi*6b>5IO6Mzcuj zRI#)izS`jdYTrZqqjso(3nyK!s7e#K&Fx4`VKph0{T zy7Eq#Ur!N+_|8rr6AC91{AM21k*xZ@g?12qjZ2wUPWI_y?BrGy+DI4);2ia!UQcNZ z+Cj!nHo6nD*bDXWyA;qm@1uVzmH!-Y_UK_X0(@E-NxvlHSLB*{udm#$T;^! zg^bX|8NuZkOx`)`ZVOJjnPNyz@~5Y&>LDGitiHBJfcld$L+c)EosM+|+DC(MZTKYv zSE3x1kl-*z1N1b1(u~LVVvwIifNWE;6l)|1S&{-x=0GX@5W}p<)!XO~DLHaoPWLOl zzAK=GXMpv@a#h+{UdyeBJ9)6S0^zJm?eq*Dp89;H&KmBRig#@@>-X0pSi&-8rHo_t z(#IipJVLyZCjjXZ!u41s)p3BsjA4~*A_bpPzUmW%w>6YvsloFy0)6fo+I-sl9?!>e3`P2PstJ|9kD~;J8j`8;VKNm!LY)F0>_&#b%O<>wf`n93F zh@fLnzm+TJu3aFBH%uj0&zMtLPi!G_`NnhW5~awh_2qT0iXEe>&{d6r1F9$nr*}u#9IcE79XP{P4Sd2)(Fh*Xc^=(I7Y z7Pq33hyIo>$Fw2^468_R-mRAT*akD4$bXdRKi z=;1~x(a=PE0teESILN1j{ZdMijg0*kpHP$pK!Cl}i2-oSQ;YL-B~3@XZGi!3qYvMT zD^VyLX8onE09PFAKgB-M2jvgHS~~lC`l99LrQwGs8(e>VFz{6{M865IDjxY#tkUR0 zJ_<_PutOCJKd#d4*$EO?ZQKkW?v|&6@P@tt5tL6jpfa}#a_amKdEL{n*(ZF_>4WD5 zhRxb}31*O7;+vMj?zgg3k>{|Spdpb;xBNA|7ax{rGh-+i`vRi1a`=itk}@$@vI#Ok z^&Q-lKU_a3eyg_sRcLF#T3M}j*!2Sk6ejnMOd9yEJ{W^~lTxR-cF%4khR+g9b6eU8 zD2JN#&%Uy+1bM)5(umP z1h{b=U2DlwxUm>9o(jy=CDjxQfGR?f(HVA%;^eo;%y>OkPf?tT?h4LrhyXHRr%V2j zUZ>6a?B-d9p|JwmRnD>ehpE~`kiUU3Tl0wXU`cwDd$ZZHAX#|_gS3b^e(ZksS-lPL z#j^HO16Lna$`&~|ve-$IA~)KVSINRERvn=8&E=x1s`tm@o!iMsMJ9Kgoiplh0HbZ& z&%t={yM%LFuf`=iE3akznn`P-D-un;wZCcrP@&)O{&Qt>2(jgr~__+?6`00~$ic0@A(vi;`>uL*qFbH*UfS`)%6@kZn!ujR#K+?!X zo>Mm^zsYE>mF_dNt+my;m=TEme?K!Sffq^tAQfG%)}e>;&gUl_k=B1DxiA}R!nr*d z{#FM!>{QxxPW+uuaeG3#oZY$zQl+9#S%OY&Tj6A_dT1)+0y1msp}AOK`%_g|HaLk`qc)2ZPLm z58Y#Icc$RPty>*~P(duoXVl7>`0bDLT)A%7$W<@B{H`mdp5$z$vIQ>ih9lS=N5#@8 ziVCB0b@Q~4UZSlw?2Kgl|M4xyI)|!dmOvp4Yr!wv8nIwPYWV*EBEgpodT>O~YH3~b zS`K+>qb6#AX3R@a++9T0f0e&tFift)$;>Hlvzf?Siety@oYZP-L@r4*@_r@}#lR$z z23&zzD}Wr9(V1s;sm@*E7Ppp>pb&#e>sDh?eHz=D#Ug_Ho9}=S1DCz>q0%Mzgo8?u zi+jO_K_nd^k);(lCrl6=8G+@B!4xNyYi(C3bctd|f>=dKs0woPf6LlNu%=4J5%g#5216sC@S%?V{MzaA{5i=YoE}ps z%(+y$VtXVvkGO;}2MU8i+($qNPuYjMTH7I-ce_Ie25jo9kh&QP$4Hc>Sx6i+s6SJ` zf5fx4gpOP)L6C78%?Mc#K;c618J_28(?NY0v*Cr6ljp!iMX~lyrZFZ*RC4`SD=f86 z^!FH*{F8g@kH^(rQ>sMznjTZJ5)QQH4ouoCL%1|cD9}R@$vE};*r_~R z`@^Z`M;M%uAwWh{I;mvchKS$GWq%+v0%WXhkMB8)?Z1lreD2K=mzglyNK=){t=Azz z1JId{+zJg?S|WTdbrp2_xDsSjFd2olL^?$!o)k_ix9F{99fH;d(p!rY&9D73227B8 zmd^5L;MoC-TP%}r-FCx|I0wS>Fchh0Jv+D0C)1nSuU|j@&bWo?>eIltTgO?X6=##H zR7x$#bZBSN)rf^Pc!{Vq1!&-COTr>P(Z+OUn%PO>GgZ`lwPyl*@60F8bhYr#v z645;Q7m5W^ywt2iaFVU<`_c`6a2{h+`o32oVr0}{pnYlEEy%1s7+SR zRtrP`8V*#_#DldaoZ?$dFPA;DL2nM?42_77RFN7Jt#LqshR1lrxK{x97*@+rg9GzR z!?JDwPS$XFJ@H6F0!=2W{f5+QigEopgQJoBsq}_T$Yr7)=hCg-=k1~OW=pX5(?8N9 zPEx8Z8J|6h7Z;0g0J*io^x8DMu6>)$-f0bdT8B;o(g@X$ZDY`jM3*xcUJv!k;DEX{ zDEP5{po<~CqOCSOq`vN^{2Trfb9+(5016)mg8YJA=Sbggu~XTSO7K3nj@&ROQ;3@?{{! z+>CyIpD3`?vX2D>^oa>k>>>ZV1M-F9j}(S3kLSxYU;SDC2_9aeH9_07aBy(e+8oJu z8vMWgN^}Dn>DK}#wV>*Zk(s+6(0+9OYnZHC5R)&r@`5AqeV{!H^4bK$>lFHMtw>%b z!(SQ@uI~AIsqgi6Nw;PsK|ti}r?Hj_3;+#Ry@X&@<&qxzeL7K6Y5sh4LY&W6XSBVL z-#f)HN}{g|vD6te5DZbWb;e!J2I2ym^SeGdT+M#RJOLECpEWRJFE1XLJ_mZAM`RK6 zeO|fuz5~HQul^uN4_5~VB@urh2iu2dNO|+%z5BjXsb2N=_SW+{ZQlcwfk1~DX9Le< zpe^A;#JlJI^AcTY?P(UYajYS3uD~clpz$@(pf#hdASr0++p06k?6}`Acjv-h-Ezn~ z;zf)=1!qz%W{;(s*@H-v(FeD z-5sy^Gj=h}O~ZQzQv~&>KdQE&hlO0a#=;V?u7n*2)}S-$IG0UIT~Rf5Mgg4Sh546q z72;F^v!b9|t~V82RdS6&lB;Vl)$TU-lfa8R&iVfP+VUMeb zny2SyO#n5?1`wNoqKmQwd12^#4#T$t$usu;;|bIV)uSoSyTYywgY98jMo7^sVXQMH z$ZY3|i$_tYtt)PSu9PM+8smd>g+-S&G%lhAVEk?Qmq#79WX8)&uD>>H@CfC5jqS^D=_OeqP~#Q1~>-sDS9Qhzy-3s3NRbA1B=8mRee1I~+-V zNJ(LLESl{FSM(np-m>l2LhBMkX0R`1g);ZfVPgNSuck@B6Cp?;?PMnW zfa;vq9WQ!{WT0;~Y1_S~fp4>E=~eHyABz%-$|mA(8Ewq89nboQ*L=r}`PN)9E~CvwUC& zO>Oif8o2J&b>^=WPj#Ku>^KKI?Nn3n1Zm{>@pl-)Y{}b=zt!XRfD-=Xuu{-zuk@4o z-?DD2p|6Fd!)oJf*9m9s{xpox>BBRjppWHn(y*4m$HG^j2KvwSZf{NYxL=;r%Y7@y z(b$APU2a}a-R!nJwAC_n<_Bhl4Xqmj)Bp^WH-kDsM;YhrsHFNR|1@9Gupx)nh*S16 zJn7YuGLjyOoC2!!nt94>y8D<&TCBr@$s+FyOx_6Bs0-+s$+9i}4brEN@QA?p66#YM zfi~$Iak;wB0fzSp3|)yuS}he3=Xx+pIuxuoh25?s*BaIA)00w@zEYl9^jQdl3s)4A z1v!7y>!FO0U;fBg?Dcu}9=i)R8K@O>vZ>HuZ+vxEdq_SBTWP!fkXiT?;ibF)29LV%fX2TA-jqcu8o)J51kZjtV zK7x7gbH2@%q?JTN!D8X$gG+A$uQ4zE`XqB{N7W)fUS#RTIUV3mh%&j%!Ipmh;j65k z8&Xo7aBiWPyAZ@OcGtyOD8-o#Z65Vdp`6U{Zwz<)-tJ9PfyW*K%)~)e@wid7LH_A!PfTDv+Xa+hsr-g!K z_m2zz;0Iq}2fP>xTJx+u|JL3|TN(rq+0cOon{}HN1IOuR-I@-(K((XJIZtulOC6Vw zf86Nu9Ku_$p)z4IpnsCe{M~K?M>q&a7k0PmU`Y7Y)uIh5_Ulk9-SiO7^w6L1&@3Do zNMa*wCt4xSS1p7=tE1s(5eI+q0ry!QnTytXjM1#L@cb)}&p+xx6$1;U z5rYP<9(d^L2iP_w>J!Q`P|d6z9ghC8F4fOub3xmSabs?dI_f_K`x^7Zhlrpy;dwcg z<>rQ=UH552E67MqEG1(oh@L;FOr^9dr*7y1>eacNmjUe|M}PDfoik8DkfKZYqaF%_ z2HKeoBtBTU#z`7EYVJv!LrG+{-wqeIsYq3me=t> z`a7x2h#;9mAJk1M^AiM?luuUmsJICWvIim4Pkfy?^iwO0fy13lG4v5)uqa}~+5abJ z8K$txHkNeVgrjFb;cWT@m3XiM3=oH~Uac4OIbBJRFvV2b5J~!V)?!Xe%Y>AG9xQU{ zu_{g)MLnXz-{RE?vGsw@l$z&Lzw(RsQw?hrRi+H#aVI&)D$inCVyapO@@*%#G-`>a zq-cRmvHdQ8Zo-nBj?OA=<##=4MQ8_Ho%%?Cc>v-`i%}VwsPo6zr~64$D;N3QQqHcs zSV}G}bg`BO_z*--j$Lwv5#{uG1ZIVP>;!CqX=oS?V?`>e%c7Ia0Z5bZU{TF}&S-8P zr7ZvY?Q^NxP8p&kC;E>mHSj$#xE@o0K$;ibB(HYkjtuDmws8{C-GM`#u$Yw!ED4K< zBbp&CB?~27ricLDz+w>Iy>v4zl5v4q-n=ioeu<;rB+Z(PBY2nQeMHZd;^KW(E}49Z zC~ey*acw6|koN!Z^_5X^1Z$gv1$TG1!4f1$aCaF7cLD@=m*ASZ&f|-BM~;HYU{d|wR?iHD2WToS>;=vw3L7BM`1OPy}5jY zgHQmLoC*WY@euhuE<36X90Pb+A>Vt)zObxp*V5??Ky2w+2|gP+DdNUPCat-9#t#dH zcUX=(8k?94lh zMd?r+lrrF4k1iA>Ql1tz+7=W!d{!qJPx2Tc!Xw-?{K?*@ome@Ox|ceaQ9;^pMzJ;{ zA2R_ABVg0U%A=YK%6qqrc=Httw1NpR{ww4Rgv;v`0X7Q!I{{Q7sxXc^1Ek_1qOGw( zUj;9sABj*&NsX-iKA?*MaHYpxrHazCupwBe6g7}B9EBl8OK`pbjt-kcCbF8TBm-wM zp5M~T^Qld>E~GwnHri!=?K1R^&45S$p2FALzI{|KQb2av*FU`< z@j{DDt5GK~ULN*OfA8ooY&ZMZtldcxH(tuxnV>|Nl{Dr z!70+})M0w6Y(Vi&B8vjPZ6nl-s?AMvDCnMfl$h&dIu+x4We068bw5!0H{RuX9On_~ zlg9e)XtfCUxX3gdpn+x!;tz$D-KaI=sgR~hkeUDObUxANBv4vKl!-U6jYYXL_8DE8 zWn10Dxni@)#oY1eMvN^K_*|1}#Mf`Xq@*jV?W*~$AQpGvR5Z&jJygD5@;KO7U-z=D zwYR7;T-A#8IQi7NKB2ZLj?X)9F!Q!eessBtXkY_)V3T3xwHRby=xIYT$-CI8EuU2K z%3Sl5XGXq%mOEOq`Xh&03nus^4Ivg<&Y{=WAIS}QOw!!uQH;h_8-i!excMHzZl%85 zh?1pV5ui4)5kMY8ct=SgcyaE~V>%F=^zzeUth&*(2iI>980< z?Z>K=n@zJ?(s~LZhx#;OBPG{d-+hd(Y9G{hP%s@+xz3NLE5*_exhLn{BP#YYI2z(E z+Ar7XbvusGmz!ol8NqAi{hb6wwk%NubFRw+On zz=Hbvren2{RM(!2vLqz^1SZ=Uaews%UFGpttI??0CGN1L>qK#p3p1CA6r+bzz4!2r z$7(k+>r2`5UpQ6;&g=ZFm%BHW8v~s6t5?UvKL~omU&xbdA{1Ix&xW4KqC>&-NaFB& z)Kjv36qqOyrs8xwJVwwqLDtAFD(zHAQDE zDqkjF%~)HW?VF5htL~3WVjkFK_%3a)h?^!RyLe8U=zjFFF^*pke?Ro92QW*TO)K6) z1GtSxzcbO^e_LE`%qwN|QsB;7SU;CJ{Irv7heijax<*6B=9bK-E8oyWqD7o?oolm9 z;{M>ZDwGhBiKk(M$#c^XAaa-A4vYS*W52Q!wsL6APQe4x;f|MQu`(XY{z8lgN-FWZ zM@D9ye*#}m1RgMke*UmV(j|MKkWjiU$S~-+1(AvaQNlPH9*YlF{dnI+>nn4eT2gkF zq^cVnwk{ElVUohi!kBh*JpXjY>@b4@lKC<8!)EY7ulvZU!l@4=#jYz}DC>wD{R~?U zn-P>rt>;EGBvFIGI^nwqEg-vFJTeTTfroNCvpE8S#2014QVq|tNGNbuqUfI+8Rbm@O##*uqnMsErubl^ZbsTos=48^KK zm1A6vvVW?@J^JuOkD!UY7YfF`)G^Fw$}}+>Dmo4`=zKs={2P9M#X+ixa2ousb0D(b&~`%UNhVn~*5pDS zV%sZRTy4i|BMIv3!Me0){*ZWJ2Qki&EbUwNWfr4^{e(C+CNJ zhOhLJ=TiuYCGpiaq|)uJ|7wt%4PSgkx#BV@BYd?PzuBk!B}C)(*E>*IOjJSV-&r-e zFlO!Cb!XAuDSZ&J5=l&WskyIA=PM_c?;qIDtgkpAKn@X0NQDmdyOZoK$U#Wx70?3i z;w}))T>v2tNQB}XWt%amE;;`rv&G7^Yjf5x%I#lT77w2{dZ9RdLTiW02)2_JNGeqDD{ULhnGG+JwZVah|$XpW*!N%?O^|$ zzE_?40S9t3> z;x`z}{G|kHL#)q3bFlnlfw)ie+|Vl%ClSwOh^4|sk$_H!?ZI+P>9d$&alB)v^hfp8 zqGl3~r*m{x{1JG!xDJnVhPU7NmO%?mHmPKFtDii+Ug73K;j`^h;hXZLzXsMWSu`0Z1%7s=MG1!jkzb8)Ur@FE^3>Pz3@;IH{72>I}2SZ$R@zVi>@csxI zTpzvWD92_fzVNHM?EUPc9*Wm*w8X}sjp3px`DYB$AByUKnEKUfvEE!u-)U&_<)r6f zEcQHD1llhVnk(QT`M_{FhJKR!_K^EYV!*-c$Eok<8UL%1+`;XUyVY227;XA`si3O+ zBwe=O+rh}DB`fO2_=rr@ib_rLOb4-G3V|Fw{J0EjY$j5f{s5)OG-#T(c-1>*#wA;Q z6yJ|X^J1ZP30z6yA8QHdnO(G)8s$wYOLVKhi{o;eE<<}nR@NXqolDem?=ZPq6)a75 zwer-;D?07o_sWji`bXW`M~X2Gtb?{Q>c1sq)gzu|xajyXSWtXRA+h9R3e%(8p7%Y0nRwE|rQ3 z-{l9FDjWS+At?$l%|MK{g5ici>9G&6)=7BAlqDe1Cv+q!iGm;eam#*nIfDU-iD-G( z)u2)NDHYla4S6~CmY6%VF|Yn?nh@0MfrQ1+Q;zN&;_U=C>4cgV)dw{EIJE3__tGI; z7;?@;%!V%#H9{sgs^ZBa9@q;TP!6aLQGJOQOx`w9WuAg!o`(0Y2@vm78zWQ|NIPW?ol_k&ESUEUkbjjgRx+Mu- zz?Aw#1!Dc$JLTwOY#d-(Y2vvv8vhT^yLkC$5W%L`98mZ5NpBqsmIX~~>pkCw<(=e$ zt7ZkJ2dCMeyR$`u^V}xq2b9jJ8~r8oCeqj=C?-)kz_+ zx?yR=3(5xA^R8^LqlUs9oFh40g4^!^8KrX6uflYW7dOh*{N`=}ru|{FkrZu0!Yla& zUoFMaPTRc23MqB!S|i^OxtB9oo_TJ>RCfo!s*01KuIw5jN_J(ZYkKi0RBcraU44sD_h2%Y1uoTUFG-bh@ZNWDjT$RgPdWDqU4iWbgqN~>`@9jNOhsUdY ziQZjklnLmxi{Fl%v~(~3C*nM%hK6yqDre-A0P>+iC`5?k`&zU4P0T*UiXmx$Dymcn zmG3tsj-nwZ5hEs_ek>WE6c`Ny2^L#6@WikD#et5s$D?DC(eL<{Ezz*>uH~XBvw+Xa z#gPF;P{e))59H((Oph!d#jYZyEau`k4Q+e$#r{)#x0d~m!ti-KEd4T((d4`1UNeho(LZ*&5VL2ovqE$mJkz#h=Q;1Nz@D)D0kz z(U_>krO%~9(LW_Fw2`?2O&H_td~CY$KK)Gjv{2)}!5a@FVfOAuc4)AmajQ~2g|g1I zP(3O+r3;iKS8=FplKGJoX+p)|<9RR3AAe`YRi$YXsU^tYk7ZgPI?xnVyn0R#Z8LV* z2zVo;SNOaA%lRK2jOrf0u;(sAx#35${xpH_c45L)6KJUlAj31{7tsE8hW=4&*xl)J zIEst@X`W!hN-Ek-UofH?LnL2zYaG)fjN1_Yw+eC_Ks|I93zd2p`k%VJ8s`9==at~1 zaH#^-FeGLwcvl<;_J!~GH@5$UrV&2XydKp!+P2uQ%6}mE`3tq+dn;?XGK_oO;{MxS z1GM9@&}cQ#?slv?=)Irq(YYwVWQ6FtjPH`4_9_u2m~nxTp^4(75facb5|x zUX$4AOIn|CIHK0yxi!D#BSd#dX)dTEM+Bbd@;!=6hOp9yzo7bzWYTCHsoTz zrDfa^BsbojAOkC(kU8e0F$>)Z{b0j!2!(Nn>5c%%n*sK5L}9)#1bALPBQ$w;jg|#Z z{k~VcKyo{iK(?`_z^zl?Rah#?&YBGL!oCMdaDO_X@Zg zwIQBe?^9JAw)ZogJY01#+z7opy$(r%kaBm~t>FQ0gjK$#m{*vEacp+QxiRr6+U(P0 zQFR;6WkLsDC%q1IvQJGjk}~=);nVCFYQ=CK6EgeP9sG{Muf(=y?v08-xn~wHzG1SS3oO0BCyViy z9O_3ii&;Uce8^sZASc^Y@!i6`pTn7LQ6o@G2O&w_R)*9ZMPAB!&{lovNAW=zR-E@v zot$>Wxvf7zH5N`eI_*p|yA92P<)!ZpKh}h(!eoHDUb*jGmJa?QoPQ zr6Iy-!9F6Pf0+C*T3|B?h#X<)#q5Z56ayLQNAWMIgfNXI3xduVu3;VNOh+vQRUH4~ zQ9?Ds^2$6|4Qm4gHl+~Ef=Y33mgxp0^2j|ewu(#-Qi@)Y6%%C~;~ z*Z_m5r576?YK@zd+nt+z(?H^e7SySk6Y9BTuMd}*z1VxdvOAzf378OC0oD!%L$>5o zzESdhBMGouZl-35p1{INn@H&pB-k{`$wgk>xn$QJaJKsnu@2+Z6uPC1kpOz|Fw0Z~ zEtxC|8(C}06_ccWi2!RvJ*ZA|yp8){_m|vUppN41XOt%z+tY{wg*>z{sstuHN;m`7 z#`3GfTa@RjUg&WAat?`o>*BOtccN);~3jQ=Gj`xfEPI**!umV}2Xm7_ae^6MbHc22f0 zk@$G_QE{&S;ZOKq=ojS6{|e${Mo8cb4vY<|y#iVnZOp^57hB`QXu`ux$wi)?x9wBR z7Sog?$lxasR=o-X$HsN`CsdQrUu_w+q#~KS2y4=f%Ioo^NaZwMz|5c0=eI0 z23FNJ2U&=goTknxlWm$t{*3t#C1szYO^?u|^OL8|QL{cxv#D+iz=!P#Om``pX{!uZ z;c99`mS4O14)1la2iTVX8@M5$GYSXJ4pJ(+xSR6_1yy{Z!%^YLci}sCFomP919wKX z#xSDS(=wC@d)05pLm%c>D%WJUO>3MzIDHxz@r3L@rtBO! z!Vf!%vfQ*OQJo@F1m+r0k)%}i-2A#_qhoqu5+}-MG|v&`u%%#u@2%}4ctUCo>6)q5 z!wMtO6d{SgaBda7dIL}9qUXd!zAKPPn|TspyBD3NhGt>6FM>+K^Zq9?0a+{g<4PSr zrmTJ;jL$H|v8>v&sfYJ$>`gZJkO?4;~i|p1Z$wR+9k`$>u{dtcd+TQRl>re7Ok; zmitbkvd`?;Oc*3pVdR7?govJ25cE?Q;xIJX(#Tw;Z*6-c<q9L()O50F>dGX zyhXx56D4!~J&Te^m>l178+%6*OzpNyE7qUUro|y8t4y8lf!b>tr?m$JAhkJ`Nci9W zP8}>Xp&G5jOs=&Ps$_96dCNg z6I%b16iJJ#1l`duc*=SSK&?T7Ab*&aZuVGI;A2wQ7qWauc7e?6g1>j<95Wgjjt}vQ za(%GeLTb<7QsuP~E0mt=7o2j);@aA|5BW!w_%#c8RG%Z?qt3!8ZfoUr;fCju-8SYiE#;=c>Tx;n=Ti>dW{KSa%&Qv8giOEpGNzyicWti zHI4K(adWz8-O?LwmBPGw*DdLV{M{(Zga(;hObZ)p+1APTl1=-F1(5MqAjW&;tM1Ci zyakxwVKC8r#qX_kHftD}5Xcq4lXsKF9QPbJ?&s8>g_kDf?%ZQODl=qE)*03q<%~Z@ zr9kSU7o?Yzo$#;TZ?E~HEU1odN6aF0h<@3^^s>mbd?0U)X?i|&jn$MROdRoiDP=us zcO456`O^8%+VdZ^2f9#0xug@By#MG2|G$e+rs99!`9E9~Eb@l_d}fPFgK9}>cI_=| zn6eL)H;A*LDzu$s1+XK6(pPTo?mjQUGWeOG6J$*6As6UELZTxk6< zrj|9ZR-~8`v{r;`K>=+FINNO}tfUuwm^v$iQEZWmVM#PSi?$ArDuKL{Jb%v>hY0(f zn4&EEh}@zWk?{_5m?)=Pm(c^eJZog^;=_CyVF~8U*oSVxSz2i~&-Etm2!Z_a{e8&# zk;V&@Y9q#wXyrY^@GFC-V$~iF{X-zOzxfI5pU>WDXea~T8FPg2U2uc7h?OHBIl=m2 zTN}}0#eY?-XEeiV;+{pMx2N7C_D^!NS*umL@+It-EMoE@_zx@qJ7GRkT>L5c1keks zn#vX(#z>gD$r^)Qk%cIhSu4+7SN;)+v#_&M-`%?UHvM`@c<=BRJSF=dCJ1W^Z~;*p z-urjN;-(1|vx%4oED@S0^G`fkD8i>zr&BQp8;Jj$jNL4%0o_Hxh;ADI>G=i+A@;J< zSGA6z(@hM6oq8nwM1j>MLva{Ue=1+(>E+D{vQqY7B^6b0sT@^gL3gZXiO+Y##)Uix z_k%qqDc>G{E29sL8DxCUiyYP_RE+w58P3O|5)EB=p|dHM*18W6!{p)V%IB zx2QscPc+$Bpy-X_@kC84S2X~X8COr~RZmLTp;tg6anQ^$hGb~>EH1f#hd)4}!CPCu+3Z(z=KRW6KQ7P> z-ysp=$LziKVJ@^_@$fbbINK(QIYJ!sQ73 z4a}io4}{IHGj8?7w*eI9Ro}BLm$80v$cV7s0P~p6A((s`kiBRhLk&M{_NyYSeEhk} z;roaTkE;u*yL7{bolH3%guI(m=y4;)dn5z4_CXQ%Zxdm zupEcg)Gkd{GYpkp&@5_bO9vUv0D4;cU91p4D^3RJ=)Z;f0m1ICc6zxO8LexJ)(Np{ zm}J@EndaFMNbY%7cVAvy5T5zD7x|;|RiMzI=ZXZVR7a7$dW602TX0|t9?`H*kdqc5 z5i3mDIc@!L(Nv0AW5oI8b@wLJX-4NulT;W=YwTwA{mN9|LrbXeJPnhPB$S1S#z~!n z^u2%LZ45d?P%#HoKJz@`@YUt+Y*kb`zbrtx_ZTYv`DfZ=>b2hOw|+m&3+RJ`gY#JT z@~0}Touk>1AKAjGHnl;p&S6wiz3 z0BbXVTkSAnd?UH^-Nl~s*P?dcoh5V6fHUPYHEnXa9oOjAZ|NpzXU6;mT0Cd;u|uP__`FxJ~h9pq3a2 zD|pB~FRtwRNVwlwEVJQioU4#)E5B^5KL4BE#U(jDp*G`?AzCn=O7TKJ-cG4FjCv$@ z@a=Yu+2!-t{>1W+NkCq&FmrDI5XP6caFJ(f03ID4Ht7C508DomOCc0RbvVJh&MF5? z+sV6NZ+#Z;0T9j``mn*m0@k7OMFX$hWT-aP-JH36_n?%Sa+NRORGK8vrd&G8sExI{ z_v@C!gyUdaQA4j_zel#)jDCOyKL4OKn`v|JK|oMhuZ^F0=hg`|{vG|GCKhje1W!yh zphD!K)5}Mv9-IeccTAFiAxmY|xhmo9LIy;&0)rq>&{=A@+3(3+^_TgN6d0_4o&}0? z*jZSOI#wP)!1U8uhr{uos*NhDwttZAjEacg!|+4^o2f57Y*@nM$ap=idTQ%InzQEI z%^BLX^Y5~7`SNBp{!cd_-Q^TR8trW30_3+$n5xGqg?S?B;TU3{R5U&YBJdkR*HNE` z^rF&$*j{y2u>Ls!D$~-c(P?-$Rt90mx2mY9ZkG>&1gP~MD{yp$T(Eo;4F%+E(YL;N z-u$CRUTvLHwUwbb{$y%Oc%*v{Cm4AL1KcSniYtKtyaN<&1+OA0!&?JW$K7(8sg1%f)L9zGP$X!qa_CQGMZG7K) zy*X+Cj+ZZ8q2a^0mS!X?Yi|dl>DOHrBbZSrUO{N0UTIWkity*{Kt?3!32MR=I14rE z%2;{kOab<4v_Iro=?0}|6jZ?1?|f$=P%Lj$8?NnIa}au*RpMkAqn^PT(#Xot#fd9G z?G7$E2OLaBf;)(&a+RbIz({~0C;0G@E+k$`urffq_|JT<|5|6)Pes`Bf~fkhFW!9R zOu5#z@dwBre+${=+tuodHvnsHGfKR2bwDb74!IDlQB==lX;wT;Ksf@@SZqmx%D|jl z5TqXj=dJt(C&$V(aHdb_%|at&-`M!WesxC`v!4S#gU&sa_Z|7nNghCBC~%H7DU|aq zN^)B zHhUQ`H!a;X_Tm$mXimme#MqufqqQrUBc-+^PhF;q6u1K$;1UK#PVGg-q8^e*o6hxJ zD~YTCD(5mdsAY`sONS|>5Zp^PUBMc;1v(%JMvq}Tf8;TL^25f7!}~>0k_2Rvmm!u( ziM96dqi{Eh7N_&U@ru;kML12N!qF2AEt+IDTaf9`v#?ED2J99y*UpN|@zD0m2TqfC ze|~D%#G?iPN$l_-Cgo+wUPWX^hz1&7A7&$D3T~%$u_#^9=X(G`$W5*3F=+g5f{#hJf|aM=NCtVH zE7+3MN1q(<;)n$2L2s&^0Ar@n@)c`IOU=LCon9TS()IdG0!Ws%XhnNItd9 z{__r#F8W8ptrL%rRoPzg7}6s+->bmdjVZ50fI;$4(qd^xW#Q30sss3l;}pb4E0wPx zz|y&WZs(nLD5g;{&POhF*Y3pkJW|WV*vzHrCEHcjLl7BbJ${>5??Scp7FOrBqF4CM z6mchsDe&w7mX%jL6ZcUIHQ+Nv`LKS$kdylI=c+BHK^U-6?s$xZKR%QwCOQ9BEB{IU zhOj+fvBZ_M6d72GmaJkBl0skoenUHQP!m|k;qUC3DQ*8oL<64qNyUF3^qaEP0`9d! z5Vuv7%#8;2pa?_5=|c5KP>Hw7e3t}dt=aE2uv{pKKp!oO)l82xJr6qsNV+z^j`Yn0 z5>2k%czA!!F&7p~lkwjFa;abHhBY03X%#W%%*6y-I?1HoZpG*WO0jCyw*nJ!N}Z-$ z23yBxdc2KEQiqwqyD6#C$cMj{L#bR*WWQU%1F~KG#0{F;s2c35k`~W%vJRp8pNw8G zaNyJ4YpYU`=W3Tiux-A@&pd>#E?Q-VlEQ&AkNmVNm>rLGVg~Sjs@CTOEYOM)e z{a5Wc!DJD;PJ?Hbmg5@_!jKKs-^6X7!NXKDafDdH%?BmYXcKoJBYjfKgFK2%`hB^3<6gH0_$YtZ%jeDQIj zb7ESyJglT-#%k|(KSR1w{%vCLND6}J8hZ-8+@A;=DA2omP=;oFMh#(nDd9o!>pu)= zZnQ^42-TX&i`gumod?6qH6D!V`=6Ybru@uYEv4{cUf0nhC(M?vdxL1LUIiN* zbrU8Qe56E6?-m7Y3Xc|9xI*G$ZbIGlkU;Urh(%i*$}-?LaS0g7x!jDk5=5n{2x+Ye zS#I_?%wKklb+lG6QM!B?+C>uIdzhX-bVQ_xjbr4M-5|5~BnZ5H$Wp^%*vjQ9)EBv{ za(+(`N=jW;aYzc4AM?|_Ki1!^N0edaCIxIalfN-r>8zJ5qUY z6jLuoD*Wt=9-Z>Ff{N%|g9BVKxVg^P6TRQQr^7cWXK;z*E(UGuqL}!l!$s>c zL(0oa4-agUnlYN*HowUTuOGba@H{qWruaSTg}d#Kk~;Y9-tN!-dI?X~sbr4Ia4XxP zHI00A7xVef-nw2RzEcRV=%Zq~9(`oje*gG+Bbm{ICVTUJme9Zkp91ZoY7~*S9M99t zt*PFjL>cZ@+HFYd#KF0Od`ZA;l4QQ>Zme%%JP>oX$n?7vqWPm<%0%~RvW@TyW-Ns@ zVR|-?@tmNC?=R8T&7}?Xx9fOrD@cmT2Uu4;_}S7LmqtwO92m#V*xs_F+`s9_Y2GIO z4l|+GeBKdoW8cc8#MGn759#DEcqvQm=y188>oPQZk9y6;LZxZnmR+EQ>#$+fGQVcA929ai~pGp41KkuS>-MQt&kNQG#^1qRX-a zGM1=pg@kd0b|0_vtb&wF-VdOBm?4;J{9_4DDfr-@21*u?7zagkgOK|5;n#~5<+8Cv zZpN9{N>Gd3&o5g~%GxOv2iwqe%%l17@?8)3sx4+&)6KHxOVa+BWZ|-vF7Sowd{c!3 zso8ul0dczscwSJ)&$b>kl+hx6Y8tw@8tB_5p8ELP1pFgheMYin7MuM2B*J#Gq89e_ zX^QXbiRm+`&*d)vB=}v<|BU_M&ID912 z>;s{ERM|ndTmkc}*zT44Y#DX)QrMX*d>OggfT%jR98WT2|8$nybd}f^UnlF!UyEQ> zTY|;!$~dl?Ci)vg2RWR{ksk}HQN}yHGNn@wiGIs(3Ag@jH<;0_IP*IG2I6SzRSpv` z*QKbhl_zLr4RWstCd!-p(D;JEGRO3jRTNV9w8t15k0k;Ex0i3FxOv%vgI9bdcxqG| zU~fUHNH?%W`M3t(XZl*JBcDXrt#0;CO^IjK?1;sS@!(acoMEhb0)OI(l}`mCrj)Vx z?ycHhAsITviyF*Mt73fvN3(f43neAz3*+$N=r%JmEN)`wdE~rjY=J~8VnzFlf5X1n z4QH46;_H5ndH!03+4*!o4R_J(lvV+x8ZxEg^mxSc6K(n~e~d~ZvJ|t~T*!=4r-Dl; zAgw8kZq1!S$MOybzj$P7F!!ArBPbimyMo^sPpaH2EgzIDQ$;j;Zj);HsqzCy??+4o z1uU)IND#Ssc#_f*gD??hV;+B{NIGbd+W|<~_f98b>1|Un`ui-KMz1dK6f;c) z&WtVM3oTJcbQ}v96fB7lEX|lW3d!y}U5CPUsX5cOIIW|h0}-^Nqxk~3$$S0LMJ6(I zpDuuZaP9i5BEA&EGxWFO+5+t0aRP>;fm2Vnr%&s`k3IJOSLK9;p2Gdd()q|tF;>nv zYoXb9H#~>i42xCl6!2Tc3;FTxXmR7MVq@M~!i__;f9ze+t4@SlIRhv%w&A|K=1szH zh~Hth=ru+ek0xpIELXST&6G-b7r|7(Oohxcrwi?>$UCgD8w_0F09K%OE#5PF>i<^rcGDXu@lTn^>#&43-@loUaVx@^0KV+yo`9*>=C8|fF1L|5Yh`b; zhdE8-Mj$cJgn%?D@Jo1pN4N(b*&Q5IVG(K6o<&X`$yvu9Oz}-zr;fCWW2psYMTNi6` zu$KF>nCrI{E8KlP)aCyOO^zzmf#VA8mSeNum6KN%G#)Zv&h>t_@p!#f>3O*I=zRG? z()8H(@+9)s)b!UauuF0IQ*UO_{c1~+~iz3v(rHoJbXkncIQb69RZt%F0v zki;vbTeY`cl#_n%g+Xi4{ZQ3`P3ifhw?=V<)%v{tw*2;BBz%du{ zKh`o_%UTnhzGZlpsac7VBLGFQdZ~USHwe?2!Q6j%U4i-EaH(u)A1);k5dZ`BJP*ig z^M{pnd#<9{76!@Q=L9>dfMAgp^JS+V-3H1UEbEl{e3mr?=gsZ)M=a<#A1WwypF7g( zzLNf~=xs82ZS-=Lx_0|#dHo`cHz4=V7FHVv9xsfXm>PYG05(KZg0TI~iTj-fQn`6C zRF&1jpn~r=l7$-cAa*U^Capms|7YPU{~CEuEjMHMO9a`-Z>2bofT@9yqXTS9ItF=W zhp_g51to*jLQ*Nbp3$HPIS;i(WJAphS0W5ydL&LoYQUMq4s9SX$FPTfmWXW5%( z3(G}Y!Cx|IHp5i6#2KjS_pe0apbJz& zKxpP%)`jcYN?QQf^A4%@>(lc3yMB9UWW-*kLm0yqG^s-)57e+0Kp7i77SAZCl-L-2 zV9sWm#Ec>dD3JbqGmgK&sQ=30w~5+8;d64G`zGk9Q~y>P2A&91RATD~Lo<#_U=nQ= z;aQ8tTXcAu+RgXNBo5O0CB_D>2D1Mi81U|!X)i|Ux%smBmWAEQ z+kOK)vXYFjmEtXcJzxLB8cT(GY4u_b(MKI)Y4H&hHDmvn(>JV4Lf)^ZK$Vb?03gj3 za*de|x09Iu6u*2WLM;ydT8X_$ggb?u@)>o6;s=zVN~o%XkP=mi_D2MY()HZrzNTvR z?A?&^cEO6kk1}A&hCL$@H`_9j8>#~e>mh?|YJ66YUpFr{k866qjwR49w57M= z%K|?U|J0VtAfUCjg{8z8z))&!xnYvr_$??mj&{od{I*3LiTRcZ%re-BQfJB8wCO}Z}~9wI%~H^Z8^hp(NBD2W(!oxyyNn~98QO4Ld` zkrnisPGrRAGl#Fo!&*JaJy6Q--@RNRnV=9SE~i?av)9k^(-w#eDeP zXA?HqDR%)swU=SHDvzGMtGAaC@M^K_EyaXNMs0G*$Cx$FCc4*-GHb>|?NYCavOX9g zB1Vqaierwqp-f$(Y>2a}tCSE{uljgEoh48IAXKBHqz6aR?B!zHA< z_zR6sf{JP@e#Z79y#3^wbR_noqyn6ilaaxnjCWK+llN>T2A=TZiC?$xY5ta;m8;_O zMZD>|yxe&B9xA+DWgpjcTeF-QQdNz_U_cELi0Qalz<3gY!Zkb@I!iJA_s|HY&TR#c zldoSVmzr#}Ds>b9lue41pY)Kz6ngu^%shRb=IdnKDH-Ns$H z`DIT#XDt`;8z%JD@5gx^Y}sYwml!n-6AZ@hm&Gfb8>^fD4TZYIFmY`J7DcuhHU2KZ zY$y~F_W`P84?R{lg?)K>nb&tg?t%x6=Lsn_b<7Z0Q7tyJNs zmfV*Ck>`P*8E+SqZ`W7J_hNrcooW7dUmh>eczK!}< zex?4YW_0ygAM3dy6ejf|%LiVVl2S-zRiyo&r6L-v#HoO7TYu3W${d2m+_Ol!alX%= zo4(kWS@uTf!8~TRkb>a}EC$kJ^g>0M#!~qym_!9i>vq4gE5m8W@Qqa&5C}pU4)IC} z%Cb(z32n2F8v>~;>R1FUvE-k^?#V5gk0`~g>HNf1`}VU3N~2 z8?p1wB$5x1qxuU2BiS{r+hT99c;kR=g)A*V6kbWiAN5Y%b1~1xiqVGWN#x##()+IG zt>xd^BmAP3o6Y4Ti~>&Nj!-*o!6ddfY4c#s&&o1lI*&{5RpCw;FEB|Jk<}1t#JAWKlZAb%# zk<8G6t>l;5pvE@$G1bpUo1Oko)2f=#rR&j~$bSos&~hd4%?{g5OlL9#ej zV{#vr-+9%RAwcvsWM)8RhjrEd$*w2Vxu}~7vO#4{2kjW@TG1jmZ#^bCQ&t8xa115O z2IP$+{wlB4>cpN%iu#7=d4w0P%3Nq(dp*lis2oswMF`11c=?m&3O0QbM;T z3QG9ijRIIKR)bFHJzdCfCqR|_2N`pS;Grgen3_eIkPBdysG4M9%!^TV&pJ(@TSa*e zDc+*kABQ!dKevQfaM)>xkmr{!bn{lyg#2ATolb-H&oSp_R?=<|AQ_-7eO$EjQb&J* zXDHH(=T;uD>i>}H4@1UkP>y^b-$VyQN*I&=eX;Bf02gH$#*9G1~rivBHXXeHNy|-nq$jLH$kF4)-`PjZ$G%^!< zMB(@awQG zYp5+C@(uf7qaZ2Ttv&NoCoh@h$7e-KO{)~4Qi$SPv%G*ysN!jH@1^I;F{mOI>$0UP z8H?L)lZaTpqDvaJp7NYb=trY>{)%|~Xp{ z-Kkvt&itLc8$#I9qO(~yR&HdWrQD4CbmrD{ls=s?N7WxR=wI3iWJoF_z%vhzF*JDM zw^T%xMa>rcIQ*vHp)&?;%!-IX zvD?tiS}v74jYMn?NMhZ{bTSiSnUW#CXtfe?>7wA?%{prQK3nI;9=e2Qa};)y=g`ZH z5{+obwa;1?H%8sX2-N7h(v?d&Z1%qbghl4~X_7J|HgV#XDxE~|+Z~?uzp_im+7KNg~Vz9QNrEwr_E*+E2Z<(Kj3;* zw+Rf9jPxXMg*(CM99Y4lIH)}0S-Em_kbvZ}RH?G*zuH%~w|W1w$a^GeY5I=Aop3y3 zafl?ql7B5Ho*6%;3XR)@6rmhpE+&ZsQ}=P@Nrq=QWuxL}N6#htQR+bl+&r_aS-TP5 z;aox~r_f!rYxry(41(3LrdXMdG?KlQ_JFJk?#K7M3+1gGx8b%xIKI_!D5ux?-YM@^0kxkbCIkY=7*EZY=ewQT$ORPXdd;+`EqlKP3jQssVne zxt^tLU~bfxGH4e#`U!`kMr6xR1aNcQ(LqEE3A}b~iH&Pp$^8no1&62*h z$!J2C#LQd4CdEkbb+}h6f(B|FSsBBnDPLR)1KFo9e&|1DDV}ll-89DX1=!5Nl~tnj zkgHrZ$toHE*D>QIlz|KCQ=j>f7`KwDD|i1&uze88mhY-j+Rc8^sm+r&m}2ciM?3NP zR@OV-{tMrI*qMF0v&Aq746R4(%%3%sQkc)ec4SQ&Ho{!C%8V6>`VV7g@N|2NUq4?Y zImN$AFDQ;$;&A16fl=W`g;Bj<&H|=f)U#9G?&r2B1k>{iL3U~s>aFh`MoF$JgXOl_ zeGQJhT2tK&?!_x|){VIvtq(Ag zFo&hqz6-uJBPIo(7nDmrr&wcN{V%r8Dj=%v|N28ocS;B%Ie-sHm$Y=x(5ZBHOLt3m z=g{4aq%=b}(ulOu@A3D)eXqEIVc_gJXYci0>$5hj?BR{>6B=xqo5+}#38xsV=GviC zV^?|~(J+fbems0r{+9Z4ZjWNfk@bb?&V6*_r}|H}%O=ZEC|;2zSXzQ7(bi~5wA=5- zvEJdb_dcDce}jTGi`U+uWBm<4^P;4zRHDgJP$g2FxY0Iv^XWXf=9PiTx_yqewIVmW z%&MMpET6eC|M|oWDoUsOIGHU=n;v;|Aq_vy_s?a$=FgfU+&N=`Ss+kIem?L7!a>M! z&;a%O%k_R>oyrz;hr^)!t3WBZ z9a+;NBrY-J+c$h4CWC(WUi0nh|L{UvcHufzp;SB8MqhlU-^B?z0m{j!Hw#({N@wv( zRo=$=Ir~QJ)7G4+{Nwiz?-A}8cQ@(7Bc^P*$UR6&eySKzbZS=Pux?=*VQ;WV+vt&e z2$>&TrAI1n1?TuZd+KrW#X0(R0u9Wq5C;Oxh_pcY#)?Z}@L`qdBq_EI`yepNH<;9g z@VF!f&sPT9^jl0kpnG=fk}44^E`kcT2z#=!Pi*@M5eKrOXk`;3+5cyl0`{1{fBz;$ zMqbzo_5?}=NZ53Ov2V}Tqvk#VL-1xDwq86XMph#V|J`Iw19ZMsfSQ|v!i91ZOa>$n zy#dxAh}pOhR9Pq;_lD0QZ|-Ph2q+lM74hq4mwp=uRKyNzW1M>5E}LK6)OPuBEVC^j z{RXls>UA>PMZ>XF1Gj&3Jbu@kj-L;8cYhQW=_Y%AuT={&M0(-s)86g`uyX(Ed~3;G zDD_x9qNbgFBs%e5)PSQg+ZKP-MrR0LqQmT#TyJ?ZknmXZa7=-`UnTPK$9}DBDb9|q zwiVI$K@b6{mrT!6EpzQKpf*2~GD&cqL=Giul=^>}8mX^2*6L~GE` zvqY>kjjOqYq&CaUwg0i0q z#3e-~d>y^S{ZXmg>M`O-+d(%-hB4J?#O?&`Wdw3A9aD4nh<~q70a0^GAvO=U(zB&)NB@4Om^+F-sFc9KAA1V3kfQ zT;gmZE9UNIkDXr0zCAEnR8L-TUfo}EQC^!@7+73ubze{mu=A!o#(^jqf^#po4_-6r zHK`L#2jX8Kdt?m2`*!|{JYCNL!7(I_&muKIGOBJFpve78Pnlo!%5yQWranG2PK~O&(n=W&Y;7lrXI+DmHkhvkm zQnu``LQXRhm8j*6NI}f^T6e?a3J~Xa1_@jyfL<%niN=9q;E zNR%Hp9^r44d-=bZG&mdJO|fp+V__|C?;pUT2|7d51BL7nR(v@eJ^B#>F{T&)L^QnR z$YA`M@i56pwBIJEjfp;v$rnSCO&pQW*20ASAYsJ(fbauvqVsf6XFgMrKZ^!2kwo#^ z*o3o!(H$WMQd#z(scrPkX9bao3lnNRBPEqrujWD2gUkqH42?wpAt(mJ*C-^X3*pmf@2nnzM0 z(g%e8zmx2u#lApkYicGR7*`$n+bR`Dk0;Kri2omcwDW+;r<^bU)=9^>7 zDo6C#!&+@%as;~!I%*y8$yvK9b?kImmJBgfe1K>dw^sL-e2j7!+J+b*=b?rpDWT5y zs^4K=BUmGi^$w%j?GO>XkpAvBL{L1JTg$olG$;_lBL{+bSV+lN&?STFXv)vkw_$%V zuaSfMY*TBQ5mWoaw@=4&F0wDap1+Tm_9VRx^+)RdlpIUy%f=L8&vX(Hf#!q260ovF zmd0X`;a}ooe5U~z*XW*Ui&z{@PBB_u3w>9@3zHheGMvig-}w1P&&-3qOC>p4;q{3l zb0Gzs{VgGs=4CJ~?BxKZPP+Bk#mibJdAZ=@C~Ya-mKp+Vw4O*cuZL{Eno=CZP?VY# zxpf-kN!*6fx#;ILY>4*G0rfB95+dinfmBEX;(x+G0lF5DtxW7CoP51SO2Do4(dj1| zPjAd?$4{~)Ncj%lDV!MR;73)_IhU{B#thF~vxpB4E3oMlgN2d)il(5L*EvJ1Wf3tl z-(E-j2l6>xmnH7$H`~JK{p_IZgJ2U;!)V^UM*I^eK!ND_^NUeOt0#z_zQ!NKvf=b} z^CIH?8-acqn*EYP0d`Hx;*u5TXUC9X!V4Dj52gzi9U_U6Zj9+08e%m{7kPzceP>Te zjl-(oH9k&;gou@bFHSJ#FRESW@069Nnzpu1Z0FVU)eWAmHgzq-4bxb(m^6c|0in?~ zT{zV6tKip%J#u4}ogdbkUXyCo^<#Ta?(cVRnrlRlU2^@cSSgl&*yxA2a+PCKbze}ZXb&&BzqY>J@7PdEu9rKAYM8mscLg>o+6vUXwCmI*Dr$N5f+#^0`dwb!XIJ6eGSp;}RRq$A0xJA+ zVs9OTsovI(@lJ56^LG3f_=;XzW8GHshkefSDD1E%OcCld^*yohV9%nqA3Bntv14Vt zsWXQ$(m$b%O+JZ>gqrKNVo5n{OL${=W#@?2!EGqk`Muwii`EkB2MuCY}z;HW)E}04&F1%F*!FJGl=41 z(kZ54td2J?e6H!Hn7e13=soYt%MZ`klXZ0+>q#neBCT}cm;gAY3rjYFWs+7o4s?_n znscyOJKmlSurKUn`!h{kWY8ErxAjlC%InWEpDg+3?Us0l##Mb>#E?+roD@%uQGRK` zU9}A54O?xhvenq(V2)d)k~KK#UO#@KLH3^~VfkMTO$92Pzq7p>J-tx%*Yr8VP!EFWASj&_cwWxnY%c04{%xDDgU)oyt=7Ih9=5q z%%M^>PGt|Ahb%i#T~iLcp|{p~K%Z7AD4J}Qte2;E-QYgx=G;(35f(~qE&aSkr@4YJ z!KOW{Cgp3mP8pZOxVVvjliJ!bK)yP&!jL2 z1ELMQmzF|j8CGT`P^{E}1t>XVwAuGb>QWpXvwkZR(wbu0oDcUzDq5z!+)Z#`X`C^4TB%(2>YY*gBRST`z}eYhjG_?YG~- zzbZeTrfjY~3@+5Q^5DZWJlR=(U%b;wDq@26`0|)#pnR)eR7=sAyQiGvvze*f6u6I1 zrS9JB*LHc={Al=^5zP)*3R28WV(9YTYlrFvH4h-CXlb*PkSS509Zxgm2w zk$BY=*RsCiVSe4=C{ovbpnE;}aLT{KXwj#*rP`XLb)Ndw+-Ol-yUrQn*uA8*PRCKh zo6X@3J9}@`qT^wRdT}hy^~GY7UhqU-`d|RE+?7MIEe`{j-H!}edpw))qxbA>JG({&W+ zRc;0~M~y9lB@ES{^(Gqzzbao>R9sKwE4R><5w6YW(Ar+XD`V^6->S#eJq;gFw4_&E zihd=frYi|2`W80@uFrHGHRylhXKdn6H#ZAw*S%CMO>migDE!Zlz)neE(K+G@EX*~< z`sl*Ag6+%CEW#G&+HzJ;W#^WwBto$MUz_eeJiGeA^_Nd=%h%ZA*&n63jEv^X!}oDi zVDFv9FcZQeg(h~*=dm@B^)kdZw)4JhZx3Z=s;7 zV2G_r^ZbeX`ok8tJg)Gc_)d!CH2@P^oFqpjun`H=lzXmfFk_ZRWP%-~xNwlL9i5o5 z3RXf*S`w{k`6r#1C7>~L_6+Ds;^{)Kj>u>u-^kRvXMg`ss3EMlHzWmvZ4)*DWX3uixUcpFq|rsBy94So5)OHA5-2g$XEmRV{BPEE~*kQ$7;f=ccHrTQjXkv37yZt zX_THQtbuQ;eLusxYz4u*rsvrUN2BRm?$fC`gsLuaU}@o&u4)W|u|GGw(TOb}U;IAq z1qoWdpaI2H^j9KYJ*N5@*$X?K`0o;qRBmTC|^XU#;X!p(`wy zC-ZkvyZ^nNU$ZI}_kMTeQOwH%jx(>46G}p!38LURxGT_4S+TIn3~QXGqAbdOv_0th z`rOHX+V@aGnmFG;@&(39D5-Wu&}nI5-mCB}NWJrwE%Ot?w{LOY!-5<6cF%B4Lu}4s zfrK$d@Q~%nJTlsFUKw(lQvv6ckUHl+sh$Huk29XZGYQPJP^|aJ?GX@uZacMLp)cnO z<meg*WEESOW&2rX?ouL9^(TCc&XjfyY5-DTc&nvZ6>WI~zR?_FD zt;fZ!2R=PSX3Na11*XtbGE9pDl%MsLHia|d9o92gjEQr0?XVlJvAF<9dua93-G7>! zZkU4QI-2DwW|p8>0GXuQm@ou4s>k*!D9IOu>LDc|zkdB)jFew$m&v`?f%_C>K$=gvd%d+lPUWv9C@HK8NWpn;lMmngL?eTbnHNhv zO$6t?FSdLss4cv)(dhnOEw|h_`(e^gPyBY6>!cYErfGIOrY|_48U5?JR2&9P4SVa} z7EQ>mT8>s?<2TP<47Rii5P)1iUQN{~M{jq&gH%Ez&*k!dMY2?@VC|7KDVl8Zy;>+o zu&7OVM+}W9yL6UnN9WB2RU~}gFo=CC5pss#gzP1|#r!LQ%jJ?uOczh%`zQThT|CFv z^5koPVmW6lUelNtrt50cw9@8RTANTTMWAE*H9e-F;gOa~B8C7Os>@Q8kVq0S)2KB) z`i#_cU(=tdd+#AfIIPWZ3u z9T4&pfByz!l!pRrEd7=!F%r@=>l z5%nYDQMG>6AeM=8yH`y=6lcbKe!aMJpoXZTh}r3*1j@a34DmFtPOfro>R*teJF5AC zSPW6sPS&8hONTcdx%a1omM`U zV0ZoK9+8@8U%IgH)^a=;Q8*?IpADUjU-=lK7$qwkFo})kF32)HI%vtvG&YDz?X>iF ziN^uEzl`{KEHJs9fDwLXujfnY*Xco<-x&ZStAQ5BYj2SW?SZVojTMo(9G_8i{ENrI zb_88}GXBIG73Pl4lK(Q*&F-SG$XAx7%@in|6wI4B2;9Gq&&LJ%NKcK*-LlH-H3naD zBT8ed5#6@Rqh7h-G}s8N1@sd%VAs3-f*7|;K^5%WC`#b*^tHu*Eo^#_&QU{pn_t`e_DjC+~E6uClN~ zq@hwAjeDx!igOv!2U!*!8B#v(V-%5KJ7cy5Y)sHu*Su4&lIxMlMohfT&90IIY25xy z`l8BaT7fb<2-YI~6)sjS^-6VnNZWe6XUjEBIYtJikGo{~y8N~jOdc4m(_4hSf4^UA zIHz9nF2=@&PDdLiPS@gJ(|mW#5!sVr-4DrD$Jd6-&VNx^W^C^G()~~4U&Yjd2{fF^ zS8P7|lBjAAuO1&`PFku$Nu{uV#q#t!eQtbmPho1Fnf8R8$5#q%6MzR{f1qz>RBjMmY|kOQWEQK z|A`$4w&hQZ84!Qc-n49WQP#aY1KLG`Ce^a5r;4@7k@NN zlwmk^`V(arva6N6%(})h*1N-JQP$r{eAIzagv@QTYq?}r;--9%i-vu6Rx17_b!GCW zMaND_X79F3QnpEw*R>MD#?f0#I5Jt4T?dKfQN35^C!1s{>ql}GH}#yXGH8oh*08$$ z#x3ITrjUBiY(&mYRLQXs#55xNhcE9|b4^ip)9*Lyb2Arvw74HV-V|Tf-BdCQB2J}I zir7CtZm-~_StUMdB*^`B$lqbL^dKLgc*!qs8+11fgYws`%)3OjRLa;R2@~P&qk9>YO}WADkubX+ic}MU z%ZzoY5<4-@?=r1t>dLN9lW+&x+ON;9*TDUu;oU}_b_0E&if4shc{4-KhF`1ihHR8w z*G?acU6-H7sQmNRQ`owr^KQh#t(TD3v~_H&Wykzw3j=wd%3EjE5se5F7jjwuUb8-% z0lyCV3bY^dB7`{pMC)9j47GgdDHXV%d?-esA@z z)A5idTepi4QNjCptQ3vc3&r%tCO@(Ni4`gOd1CVy4)0~wzoB-t-!M>-`L$oVjuc`R z%gbn)P`rm9&~rJW(Xh$;zUKtH$CbdN{rTJHrve)Eiqfw8`MY#}r^Ys)3!k6&v3%FH ziq_5Y8WOHKy_}!~NIEOK?8#|1teAw6=k{i}941wj> zCCUnS6~-APE?x~9Q<(t>lAnxRgjjlZniy@D()7IV{!{ws1~o8n_&!jTI+3yJ)z2z& zxJ7?8k>zQ&QGoJ26bfwD-1n~ZZmp&#?Dqh%6< z9JOlgcV(^H%}qsSpM_;vmVZ$(EDt?nj)aUVw4EVnoo^Drh}H9TEY=DwDp%GS5w~96 z!+@#~P!SGJc7)s>gXggozdiSEEfdO&u)D~$@}Jl)m%CF}Wjn7Tes3WIv$5o=iG_u{ zyT9*NslET^T$JeyLK*Tij^mkS6pKGNLC2q=GAfCXfMbkM^}2akn{`^7x|ZqAv*qy; z_2j)SU*L)vWu8(ffx~>ZtF$4A>IA>K%d#@$kl2#gH?*(}8yLDux&5rUtO5s36bbR! z6tBvbh~|d|tb*9VUo=0cDxqTp?5NxzUpA8^!wiVUx+#X+Iyl_pbVmZ;JHso<%WRd+ zkFM1%bo`=!6EYg{9 z^h1g=)H^-|1fXYxDmiu-&c#Gp5O^G{fsX@f7teq>UHy2obaapvnOVKG;WCdj&r%v8 zDt`feBXv-DI`mDmMgQSRKQ09zo4iUb#z|V-?54{jY%H4Twn(`$^Nw{n)VaADY3whM zVzefJCX{Ie6BFNR3PG#AkNE8H*Wj&pmrUwa zyL_w^0$Fmz(42?lQ@redyNl@B`GDR9+NRbB0;7tAMTyrQY6PH(X7tGfZ}bXTV?sr- z(O|Sp1}eIBG1;ozo(lHE>vz$SGR(DL2C#ide7g#0Rp2#>V^6sj>~k4L>9GPkm2MYB zfdI3`?!|m&%WMC6{r8L+e5r_|Rh z#$8Bq18b8lc8QLjjcK=$Owbgk-}(ESO>j7RJ=15}E!-yvcZ&WqdXkxdUk~HD)PL2- z03D)XKH%=vejp6RY2Hzoy!o8`xQzLTF*)AkbBLyRMAH6s`2uV3Pd5#J)xIM=>3U?T zu$1Pv++(FwYTQOv0?s8Tl06a} zFkNf$NoqazBNfM>?5_=0GNnKrND;i!E}%(Vq$eAfiBo+*s5lR5jv%8WGO{|#l$s!( zKpe{ZgqG;8u#KDhR6qXyp`+(PFjzeXjch(`?@!y**Rw7F91L(+wEbHXUv~Sg z*sM`2n)GZQ_(}savi$TAr1_ue4;%=$;JlgvXm}I-iMf5dSp*mYD2T(Kkd=Gx;WhtE z@V@}uDBy;|__K!1^>QWha&-fA&jVvxYQM*eb?#DORkIiTKl{H>TpzRd8#mgW{`lTS zyUuPhM8(UR7NLK%Ut+z~Ajs6vBPf#3ln{G|IUeydql~+l1Z=PB1HV? z{aWl)D9r7Zc^YHdZ51nFZ^cti>?)2L5-lUEb6SgnBvUq0VWlCTe=X6}^}C>g+jo(} z^cT@mdBs>?@otg8sU#}iVd&9(Vkp%Y6pJH$_w}0qTpv&#aI8|k$9QHW*o^8l`h z55QjT27(~YwyO8$vxfmg2x~IO<>&LLP~akpy>&G|JhcbCC$N)|BAQbGtG+>z;s%-1 zT_ia=xtz}lu$8fK(#OK>C6BFGs$c$~@@_N|nb`SI4++=h3=v>OHjpowN!YTf z>GaeTVW(LU{0rFGt?-GY9`M z7kOB2wp|6NMedXQ0KtS)di9RqwI#0!xILI*sZm9{MTK5pAs>goD>qE4R5y4Vp+AOQ zRrrB}+gQdx3Pbe-`~BxuqG;2uwZ9GI<(;Z@nj*{Rdnw=CGm6}e{zHH`02XRefC0TTfFp>t)v*)F zg7fjO5q*O7Vs+Qk?J7dwKZ*>N@LrO7cq3r16`>k??wIN5XF4DDMl19qjDGcB1tCEKBfyHnZJUb2!anF`v(7Rb};889}@T;;2k8=f(wvS4ZN5Y zNcdh6UR(!gmL19)-p~H~|2=hWK6L$yy7)Z~`&CLki##1E$MNli`#mlC?Rn9_fNx6$ zawQxd)fC)^0LdslZ2k5$jBpV*MVmZue_;r~|cURjJGOiMj zi12z&GZz2)lFdFEa3#tWa|qNq$~y0A4^w(QJO0Xm%f2o(XH!~P-nglD?_>JM3E54S0B_ze zv=AVJXcub?aT&9@tw}`a9Aps-LG;YbT3{KN0E57IaEHyy4D}N}y~bKS4qZ|s@i+Ax zDO*r2g?n_e$aOyM)6?e56Y$wn6{Rflt>P{&`v?%FR`W!Ui~d?}4wQSULS4IR*|6yE zioOYHzlMCgzyBUK1%7$V8Gf_;_;aYvRkdnpgjwxUxXMt;>UE%^X9eD-A!50hf$_Oj z!uRmlpHg4>%Beqy2s|8qnH2KceiXL7_&u3<@~Zbwa*fYktl$}qkkM7Z1vkZg#l zv!8P|0!vM9wat5;ZUv8u5^351wC@`ZjSu?MP$92JFW%^kpolkHzk`~I8ZYsb>11zo zdv0_cDZN98fDI6eTC%g{L)*sf;zgWI&BtTLe3{$)c}<3VxGc$z}86lnA~~a&+=99CmIm38dGu`b0ATE=n<#t7*5?pNj7KUt%Pn z8MykJr~BCu+4 z0yOU{wZhQ+Q%b-X*1BL+zq@fm26EBn$PBh64(&?Ku48De(Hr=?r_$xj7BS=UIg9OJ zmvvH0S&W6Fwf}e}imP2@5t?L~W>9-^=zT+_QY(Z*QM6SapAbbSZ7O-xr9>7!(f7s{ zMmBlFUZ)`adisrCFZc@=#{fD&r2L}0c~A0_XpNGboVHBPgm4g9OLmixa0@hjj&1KT z0N}rsU;C%*1w}(pEcSXx3XTP?OL4T{jVr$m$Z>RWfxKpNAJx8?UhH{xwL)*a$gL0f z(|I7gV!8!?=<=k%!~EATSt0r%_9s+RUy9ario^@Jf4jH!Xum0KDNi!@`8_(>l7>$; zrf?(!yH?NR!4qYz?3YEyt2B+-pqY9GH|nYuYn;4BEDzaYz6aGkauWEK{j4%ahiIV{ z{_s@`Uv?Q%Inl4GTdZYXlEwp>>oxsd!c8N%Mz-C~5q(pEkjgH%VU@%ywVWkud1@)$MIJ+-|m<6t=qto~(d?mNL2@xc&lYhu-zmyxQJ zANQEZ^^1y@)%d)e8gqv15Op!3>Q5G(#*kw=!bSzwoKTcrc|p-74DXJjr4+M(w0;HG zp(K#CRY*H@bV&Jo^dyYwol&Gorw>^jr~*d9O?bVtcTN#7Cwu|8(5e5ZnCA z`l&pWv=y`8DLRv8!r7I?UjwssFzJ=~|JLN|7R#E>a+;8Y$mTa%DUGk0oXQkuVhJYZ zdUq_B+;*Zge*Y(GrGG^;g_qS_Mj#to5q@=RJuZ2vJP#QVhgEs$Z=x5bnWxl%UBqQv z$s^@ynJtc$CaCx$VIgIw$V_5dYd$E3QnK__ltWd8S(O7;LQ?4U)rBmX)!Pu?`bJ?h)j<#SF%;=@nVXpEK5}Iky!S(-*^hjAOS?G0p|YHrS~bfM9RBUPOHRCZjO7) z203ZmZW=9qJ*ZhR2FB-fyaU2W)%l4`bF4=woP#aR>G~r=O(z}#Rf&k%d0=6(4(l%9 zNvk-q5KSqSP~}F;3k;|poe=9J>2*3$1!Bct5!DoVhBQSmEPqnVnVvH1zib5zDpQ9h;d>(J<)TG7?2fs$;w-l!+v)FFBGB%P zja;NO8}Qp(->O1rHWu_V`k;Z#I@DH_W;bxi(S8S6t}#wqBjs4}SFR-f5k)z>Sbqc9=Zd&j9#{Ks zT^TOsIX?EvU?#U~`)qQX-dnG8qnD`f@4Zw4Kb;rbRvePNfY&zPnJF8DB)$2yn0 z`RU~MNrK9(w!FxHjz^sL5Bn^;$b=6ftI|Bx4_936QjKP+R6OIJ@*4I zk-gdyvBf=YssHG;PBrzNf(S}_p;Ou3sh&-sf=4STQh7$%c_ zj4u_gRQTtq#$_Xa3vZ`DRDDzrEul}Tm|xgQmL`m(O8$9Z{rnLy+^K- zg0=m6t-qxP)k286aTfo*DtbB2rw&v~{)oQ^_G|&2{c7LoFv*4nEluL7=My5-vA9Rm z;|Y4Hk9Ndgfo+n#vs+Pv_kWxwMw#h;x*ts{*HfbVQXcI96-{2%cvVC~{G$1A(82`M^HJP?Qh%3gLl(FVmGgE(bxK zbrvzDaJrxceWfNsJK*)7st?Z0BjbVF#yc;^z|zV5Bm@1rCrke0NdTcCFT!d+I;|N* z_OsW3wXzOxBQ3*;AWg%f5HW=B%rTBoO&(7*k1v`GX+)v7e=@V)xzx3hn)XM(Zp>CW zmDnDk)4vzAlR=Td*K&$(ij#N(my1&PiWvBLe|?t^d2Wd1U#l-OL3x}HG{Q^UK*Y(% zlAai#{g3%GdBmGw#1gm2Tq+!b{EWii>C;M3 z9Hw0dU*P}dmof2Hl?7B^_DW4D!xaw`KPDiInH1YNZ4Qw*9Rwv-(aK86Bn@OZ+MCCr zz`n?eqMr~ut;B+n9TAh{nThj5gJ1p&YGasq-2C5&&Mg1_!Q&p2^gX1_l()N8gk)ZE ziLM|6A)_cKQZ4P`zxSCR&~##p$aq4eGVSveM>B~PZ0YujE$g-rf{*aLF; z&)fp7Si6;abO|3=9n5WQ;?NnnfsG?w_zHNhuf{{6Gx# zbmmjQSKnkQc|Lk01?5>PpEAY2twnUFN~mwpz1B(H0exLY z@v!HQ4!xvlx**!Rg&wOHwKVBE(?rpnLBSxd5%lVWbh(N`3E7+lb&$LOqC%IQSN2JI zkXYbnqT*Sp?|z`1V9U9|q%Rm~8M~_mD-Mw2aB#FdLniG*F}eV1xBxybnX*p-U z(6osABx#j%EDWb8Xr^BVeoiBk5aui<7XxwXeAr9UkIA5fZp7^VKIFF#ycFYg9aELx zi<1)y(1}IG1|Fm5rO{3v9%;n$PLkzInR^v0SDqrWjr-ezm)r7Vy_XB>2N8AD z>mbFEMkLV$2IvI{wl-xwn^Xu!NK8Kg0wim)ZtTI^Skz}dA}Lj^KV^o$Gv>HPww9`g z2weu5ahd&(PY-`&JgW-*-yj~^b7wP=&WVaVQ>#xc-FvVTpXm4B4lA4LPrAX1Su|MY z=c~P3ySA-r?32Q~lJ;3F=}e??nk$1ZA#EYElg+M85j--vesAH>%()20H-48JVQ;*A z^zUl2>X@vTGrRr#Kwr6swVzJJnBY;Owp5c)PK+ z#dav`-wpj$`G-tpD(*dTn(V;5AvGYtd%qQg3;51cbi#qy{d@g($XACg+^p{sJpc*w zU^3equ%OoG?($y(yg4L?R5o3=L40ZdG}iC5r#_dXj6ffb>&V-%A34Ihb$S@?S&u#4UXe!)i%;MS~1P&(IYMXiqt3`7)3i>%}%kKzRK$uSN!e^jr* zfx^1f2Gr}f9rn;im z29CDmYWjhzrgsmSNadPV&^a2?&FIiJK{cB<6GIC`QFd!uo-ik-;zGyvbjY0~p8y9J z;}}Dc;HH(j_J0OeHK!s+4GH^vnZHWY*6KujAzbQ3IDDN1B%ZgKoAnmkKB6QJoxow;5CEDU7yeT# z%P@%H4vcXd-oLwy4gpNDlcEEVV$w&Ybm-lU6Tz8(KKuP#9V+)v2Lz7(VP8alq;_8y zOH;WfY1H;90N7dwoPA{gQqvi*gox?;^02wt>B-rLS``WR2kfxGU3H7cA)qagfMvA~ zd@-H(sd;n^#$z#?Di9!^gedD0VThXtjJ8l=?=tIypGqly9UePBct(8jSDQQWCvVBf z3*$#ja!`wLwcG3lL`QoOpd2Ei(W;e@&!ERwSPVpy;OZ}bR-ZJafS_*YNsCNU6nc>3 z(2qX+#=G)4+VV2;3kj=MZy+*;2Z_a`@0wq%F%|Z_TMH7fr?eH-KJFC*ca=-NyVDs#OoW7U9u-27Jx;JU9;8lOM-H4WXuEqdpR zQMR2=?Kx=N`a;2DV^sR-)mi72QUL;pX;p_R9|N85NB|Gv6bXYr&4{Uu`P>meZyOa~ zs)ShXeJA%7KFD%jLh^qDn8^V}vHbJ>#W3|0^Hy!JdmCL^{eGX1*VsQGewUX2GxMAx zXaTbJsHxi6^481nD@Jt+1n17A>z6pdGraz}AdMwMBEjbVM ze9ujsB|fkql7i- z5JPvZ3lO}|$C6tJ5NOs13+H+MkyB`9aEZhj%PV#2P0-8a^8AAWlyYP)F&s=7C!c|; zNa0Rz5NQG?E{d~u%m?O#2f*n*Z5&25q~56LUrEG=Ie=oopVpbOQ^QcwNVm`c6kiC* z|H9vml5F~u?iBfcvnTmP~|NHW%-#gz(Up9i;V7BC&S7^rMR zR9~QP^*`K94V^)Ft%WQJIDERf1lBWhDhkO!x^z>6S??XVJj-%^Hpgfyp)E>`EEBT- z-$A&+NY=WNSTi)xg;r^(z)H`&72N})xn#A#i5{yzUu{WYs9pu*d4Tm>EjW;sea=Zy z;3+>5T>{xQM3jQm`N}3pvt!hf)E3t?Z=6Q#*hQi4Uq?X{iQ2e!Au)8WfM_Bzai}@a z?1`2VoS-v3@>v~s_mcslL0DiVLDJAS1#}(Lq~hH%NtVjec0Zx;z7;dLUHXXPQ+i3sm?)VxC%^=h+PTDK}!5-DF$9CWxHPqkQJi3^8-a!%CZ>lAfq`^UR?BJGwF{SvWv zTfcvJ{nb zuar3hacWmg_5M|*aQ;wpe=nUq>LUF-sAaj4rcFsSGu^D1Z1Xtl{iCk5%js|*6<5FQ z1(Bwu(MI;RS1^uUr28i?Tzgz;)ox$8(vY*g9-3_qZcr#Rz?qZ#!dX~NQB;M7IO5VH z9tkUI1bb+hz_;mjf~jSfdyT%ULEmFmYJMZ7nmlHx{P%DT?a5CZ8)1Z+PJ(2qGSTYI z_=t#AIjiE0#;QAihPw7F`wm_Py)kTXn=otOu%-O7qCSw3&g*>^5Tz-}eU%`Aqg+hM zeQNZ1Wo*{x1L{<5htW=L7RhsB z0O7mA3q``0tEZQ*R&yQ|R(9GQzWNy(Eq#<;gT5@ODb|=j)=bCcn(#0F=qd&|KooAQ z=rQ33?uE}qu3+3t(m85ec6zkDg23m(Q(!>E_dL0r+sMJmj{nJ3E)Q&)KA8HUxcwe7 zko9o?UHXmRWPkF0;5hke;LLdS3pOt9-kmYatw^cBLFwX}N^a9U`#v(2|8xhz@Vp1tSM^)zOqOzU$UlD4acUKlEA13CppcBm(W&NkU zjd(Kf^m39An{@Eb0#Z3q17pdT=MUC+(CnEVVE713D$b$=8hoVtvms)R*o4|#T#|LZ zEY;QWEmc4pJ$+?K3{7-c;ibyEZ1&_4Izrun?F+2eqN^P6valw(6a_7PKS4rvO{I(` z*XN+FoC1L=)-V|C44}OMuU+eqV3NhMkY2|!mi|_;+4o0$=1O|W-|bP5;Ps*r(om7j?T!HgueBeE0&9|)uMSUfwe*Zmf=zPQ}CH8d~hj4Pt5 zki&#bE(s;t@=6@uF-m>_OgfvJ=1Qz3GN14w3M)6e zjk@hD&l5%zl`l7-lQ}j994cZaYQc z1Qh1jrUn4PFiV^HCMm}vm`X#vm8#&xf^3QOy>bI^aPL5`D%~&=}dymA(hQI zacYA}+w(#us453M`G$>Bj~FbchK%kLk*a}#eLyx*BS z&7YJll|k^K{DA;Da>xDVmW=|_sY=82KSs9EPx-5q`zK9y&BRA5_ z4EE%WaP^sNtBf!n5?{nyD3vZWwHT3GI47}dr*lCE6D~<>a=$R4j?k0g1%LJFg6V(Y z;K-j-%*!%jp-j|OQ683L`S=X9DctXn_8fX;rS1Fy$|CoJs2{fg7{TbbF@tp8VmYQ$ zW5sOS?~?F;)&c7K=`g;8(vx_xmv6wcu3UGVoU=c;uARBqncaEccjmdDJ2EH<*jJdcJvtST znjW812XeO%TLz1J8UzAmm8 zp|Jvr3ft1}wC;eaag5jF>ZR2CvoCtwd`=Pq+lPa?UXXFE=ni<0R^8=sc!s=!wVeyL zbtP+RU73M_5;t-F9+~KHHQ&eN)3H=Thyy`CAL0HI0V>+UJ2k~y9FSE?u@s^yr_;hP zhmBiXTG)Kz_A#JMlFSgm)O&PSQzg(k7?+Ae(NShn9`!1Z4VhGu6TUyFO5rIn6v9d( zGC(nkNrg_m)EnlY=z(18vIt;8e}VomaZ{UUXBLBstC4cqPCmcJ4dbmKzz3mG#0_#; z8uR2M3pilb(FvG+h6WDnvdj-WwubX-Iy+dBn(8KwYFf_or~=Un-#`{Zwa2eFC!v@7NC9kEp;ds?VU;A2hP_C5~+-mK}q{kxgxFrm}65 zqpE1Rd}wT}bCvKiR0}T2TR-i%!@CHHanPMQJgb<722wlq09XP8bZ$Lv%{k@M? z$Pp;C4*`q`Qv_ifJ?s?UxS@=Ouo;SU!DqAgE% z`=S6D3m!^={dZw3fv3q!gqg z-y&^3CuAiKoyIYnvt#2JG#6^wI$f(B8V+YRx`us^WC=Jk_ig5}NmQlN;=jouzc`oi7 zUeAqsC0^-fU;WGyM|M$SpT>^!Xe{Fu{ zh2b7+gurz==PSKdP_E5B|CbJ=H5SSY%WJEA z1*#kG>rf_NqT|KT)BS!1Xvn{{oNF`5o;f@>pfV9vW%|-%bqwT`10KXrf%UNL+R!WO zBgIEgY15ZQ$2P+p`aXGnpnwKlZYO9VTZ9zhz9=}#B=_V@ihsAt=Wt>x))I@B5Dx35a|{d| z3+1~X$)nmJAiRlFO^#`&7nU##^zddLU3;yQci;AVVM+u6CUe6olo0UuV0NlfCgRSg zx-RJ;dnjLnFVC|OAclPej77y&jW1lhuU$q(pC1H)W%EVlzTbAziCJg6AY%%*OwAi= zRF(&^S3RoKn7+})KnWcj6(}lJ=evw_Y5ok@g4j6F|Bm->y4_V8K>}KT3p8R@7PXQL zS%svV*%pe3>AGZ__0OLeY|g%_=nYw`U?q@#m0+$0?98U)LQ;)Pv%e2YA-$$4F(WJW zOSG(2N=Wu$w`bRs^HEpJC|DU!zwQ%sMc$GVqjaAA)OP)&O&0AkR`D&oWJqCU#uR~> zY5>C0(^Z|MA`6y}FBm{=xW79AY49C=n7CHiTF5Qm>N!rm;YFmP5JuJ=vX^QF=A<&jGp zxd*-LKri|7jf~EAXCUVD84v?+ZFEnDYCo&{B@NlP<>73w<{+a0u_ONt0$kkV3)?MX zuW9M>?NvDrc|3-NIy{e#kfODEO@+c-=?m?6#t&eIE_i&r-COH71l(*k@~^{D)g2qG zhu)@&A(+s{?7dzkt4|vv*~04 z;F@Rl!NqPt#!uJSf{CWkD4#d11WaaKEb6Q4k}8_6$Wr-#jF1Z*X6m#>XeFi@o##=!Fm0!zX^tZ zXx1X!-V*8cmR|_r>V9pU>a?xcOMsr8*>ntdEmoNAHDN@AR>`hP3*2K)rI%psr!xB3 z#)W^6EeU%njVdp!|2|4@<~QY^)D@&uNa!dPs^aSRW7;L`xOla>L}<$_zwXPr_0P0m z++&ygYzw^&f+v7!HH-1Vqsa6lT|(UV6U4W2amYJ#!cnkovQA)SUc1#;D{ z8M}waBb>a}53!e&n!^|GU!2Bl?P+-`bV!LMXeZlI1pUjU?v@h;%#005=s!j4nz2Mu z47l%$;DzksZ9WInfhcx6tN+5AAghLrnXpdr)E?aErjk25pQDN%efCgH02m)Qx!hhH z_@~=y{~WUY){+YNJM$ZSEFgG@3}R>xJqQsEl-P>|n2{1iJPCjN(kE2&c%G#**H%t_=|Eb;* zn&o~gn)Yhwe{+@$K+;bWe)6Me87U|bHZ`Aniu%s0CiDi@z9#x2-+rCzJo(;eV`m9fnzdaq zP%-rFFBT*HluDJ?V^`jr<4C*oZ3-+q99DdiR%~0rqi??DoqB9nW_d zqISI0k0byv0g5&prR#64lW8G)I0$^x`0sM$oj*JeIQFy(O9MAxH5w=U;khp?QTXT3 zwLU@OqLC@`O$D{4XL~~+f1(b)qWu28fy0}fDesK3928&)JbltXI&m&5Ni#L3R2mj! z$OFNXndJ~CbAaUGseLVOGd;UQf2k9sH8RfYKVI^F7k7iw8(1uZ^JYqXS?1YGH6kDN z*I!)ygsY~2&I$2IUR-pIzufU%Eg&vxcH1Wfla7WE_ZPdBPtS@|4ro4Z@cp-a?ldTo z+sO_f-VRBb%*Kouo$cbh>{uX>+iVM>_DbGOKi?kxv%Fmz8F&6Q0$8A%FR`HEd`sn@ zx_}^rVo9wUJ0SD-W&0s|uE@=bKhTLGjL~TJy1e%6s{e0$iagm~Isl|3+ATI}zIzgb z@fuxiB5n4Pz%LX-=CsHp+!|BseolVtzS>{4cvJZXqGZPdHsiHoPz>GX?8{vMxy6O} zDl=*$)A~OQq(IevX3T{}%~JE4kywY*^Q`NP<-g5Nd@cggbZr}HE&=|!W=bB9^^DNf z?C1RBlEm@g3dtR zVVfMvLtglAgt8QQX;H+uCsT8)PePe5shVW8)3cq>Au@T8ZOy^w-ZrWv->FWVGej=d zl(cpxEN%|2`uG$UX~sZQZvWIdM)k2KGIUn|K5o0|zLPzzzM{%S6|8y?_X(jKYT+RT zYy~+P8@Ob3p2Xl+VQ&t0W_?agmZFs$d3bc>JO2RUD!@2-D;JnzRZ9ICv2=cU zHS^Of8VSg(QY|~J_iPH|mczapjo`uQ^JfGxV_E|zTw0FA@fmKnY2H-_#8L%0O%=39 zvqtJ5B-dvto0k3Km)YeHVM5&7>W1!t+sMF*Zi|h#2vFp>`|NTeBwidmw1fa&l+KS~ zG=m{tGT$uRiQMQ|6N01%E3Fm%Z!M#FO6=poreUz$r9S_jRw1CY`#OmVRVh)C^_>Wv zU#5fcu_{W4%ANZSd0C)}Vs>)TCUmPaJ^`+)%CtS=u-m-!8C-g;=mj|2d~zHmT?6|j zymAH;MSHR6nWUhXmFSK}6P37V9hmng@hC8_%NybzHCmb^^hY++*N)P^?F~*1CbT|5 zSwe0rE8aFzkX|HH`#s;6~wh%%;!&MgElXux`&d>lW`%w%moI-rQKG_vY6be~C`2;vDUa zw_tP04!45EvM4CyKO}&wYHT~A`AzK{=V=F*&nh3c6l%mP2b~}cS{;xW96m(hhH3jM ziC-u(@q?`C0z;awIFL1{CNh}CbYoum%;Ygws6}g5Pxo9J*yI@bhhj5L^vsP;E=Czp zx4bmf4-=xvQhvsC6Mncdh!r2$SKq7{^VqG#7S(-R*>bHnG)ytyY!4u6|Dfs~FooX_ zrMDvLR$-Zry+MxFlg|drEKiO36;xK#?DGoOU#0V?ZXfe~p8KRB6)MhZ7HQ*S)*C6O zjyJXbDJJvR%pvH3rOY%6UuQG7xIIUxTfm0Z2at(%K=5G?NwSMmaB1x@aT2Oc&hmtJ zdm-`t?uW>LBG^feM_TXg4lcGnI8yI*sGjM9|BAPrm7(isJ`+f>N?|yh{N4LDxicBh zB53%<1Ad<~G6RbRb|nNKToIt!u^m9NXE8s}E0ZM3Td{dxlu=l$bJgFK!KF8lBJt}? znIYu!=g&Z2dl_)`9A#Ie@@ee^=13={nF2-}V9c7IKsxV&{N{%mi8N>TbVmJA{n0>70Bfdv(IR@&f>Ce3OmeD!gaaE)7_H$shjexvw8{ZT?N|thDK9 zE%_2K8P%)Vt6z_t6fsumwn6S=kq85H2I(@!ZPzWw;&D8knX7ujG0%NKsjFHA!OY1m ztQ1lLb91Rzp)sOq&OluidM2qN{VQFMe4$#s=X3|tbcuhiW#u!qkh(12|L%Sux3Y&R zQ1}0gffH+Lieih8a%>D&F%y%5dLoDI+#s=uB)_#?= zqPbIZn;nomJBgr!b+L89qGbp2&)CGjeE2;RKPyU}KF!DCz_Q~5Bq2;@ zEDX;OPM#|JNS4$>D52?ZgfUP~r9wI#IT&`Ex7@P-hB?Fqe#jmdk2cTGx&8PZ3rr-9R${&{90d9^1 zae?7wqnOw~X9R?1(Ysbl6eG+m;9)J<%94;iN!n*>`C;qBfl;jusW@2MQJQfNP@H)H zv<95yy#XMDWxt;(1IrMxwfi;N;9I?FIn|BOQX!c8i^B}eu|J0A5n(jfUpJgI2VN7e zoaGQ=anb*Fp&XYwflA{r0$*HA-O%>>On;)KNX=%|izDAlmrM@%1604$?aw+RNu$Xo zd`Z5|`mXgWA})=Us9b_%xeJZOTfin5Uj{v5+G%zaJamSjPn+Hi?;4B<3~d25FeZey zMD+P~G=vIIdK$BRlj&YHJmEt|mzWO9EZhJ^+25|3hFCUWoyV?T7e&|ka^lxFOtL=^ zr-!SQM#UVHgn_@O{~5i#)6jQ#iYn1u>*F*mI{+4ahV>82*}XzzyEXpN*MNp`ETqe8 zHIO)V6O~K+J>z#t5_ldlJVW%K2!Z8_G`KrRVz>f3G+b# zKtu==Nna&{0ylHTET^~pz}~#7V2zif92}_D91OV^3lkBbA-;09H!ZO4*wY!=8>S3Dk31+4 zS@`lGd~6JqKVK5_61l zYSQD1gopBI6@lUONW@T-wwcZhZ28R)`DP+n(&avawDXip7w6tRLxFnBp0-9X)XH2S z8VD8y-4Jgkeo)+6Viw%@$ssySs@9CjwqdW(tb7i{GUD=U60>>>LlFF_6L`f!VT2K8 z4BDpFfz%^iDixqX^pI>+jKr1si%m-J)`h}=a8Wj`V#qgwr2Tagh7xy->9V!gQYcA_ z^>EQ=+Y4<}l$WQVBlXUD#;WxrOXhwgvAl5y>=|2AQG`Gz3&kBsCDTOAQ z>MT(Rc75AwYh<-+dOGi8UUAw!Bs5HpuFO*E!QlOk_x=_*LH5E0L3@y=>Q``hQ+0Cw zh#a8Z z7Z@%TgX1HQ4A;bC7O%joT#&EeJF2dNZ2@Y8&O;|uH8UodtdPW@d69}^j&Y$S?W#of zL^U5>Ap~j)(Tljhp7<#ics$b#ivE6ejukusYU%Uu52#0>6WzIDru<)0r_@T~m86CX z64_Jh?8p6T_S2Vmm&kHN99?mOGT-z3sOO6RvtK(?mC5LUI3|dFRy|!=0-wMucxW7W zSnci%aWXC-?+JU)l6!J!So6&2dVaMQFa;X$wtQ0-{(cZs`CZs##IX*~cCj{_t4$cX z%18S}<*hyPqoo;oKQc5aBT?`f~dTI8z4^`fRf9;}7{#Vv<~9D{}^9sW=X^lkTGS%Uw&$d8W8(|--V z|5=x0Rdu~Trto;ST^~ld^K@7~`?;BiZBD}9es@*K9Y0=27IvOtS`D{Bcg@s=gutSg zfR!X?w5@@v(R2!FQZz%rV9%64m%a`9yJJ7a6(Q{k0fIW+=G(uO=Qi83!NyX*sv#EA zjU?f)b6*R6^sY>P{B=qG8at(n_>bhSMwy7)E4^vahO_zce|Rb-oaK6Ch~M!yxF(Y5!)> zgHadLvqcCyA@67Y$G;%9OaAC``RF?n>127|^^q`JYa(E2I+R|!8MPFlVjKoiSXyN~ z-dk5kiar5m8q;NsD_`5VZJ=K6hu*;B?5$&Lgyur&fYgJB#l&KKoxeT8?HVl;C!?%Q%iOKbAZmF zgWcT8ZEjE2YHKz3H-jt%-&t?NmS0nyjm+~`W-j>_n&XVfPF2PD3Y5$6RLxg~ph43a zy7>tF1P9leGYBi#s9VI|g&$^DFteke=H%y$o$@HOp%I?&!mz^Pd#VL5TS!&46krw| zFFqtXb@3Ls!9iC#Eg8py=yvdI)1Ww-ejd(d|zwlhbWV&Cxb_m<`eTOMXDn7NXn`YDA0k{gcQS0HbObhsARf#q;UeU6tSBi+W*=&r zp=3}qpy`{ooTNyQ(5sHwV;!LLVDvE8j3M~V7)+fes|mndC}0+ofs*);U<#b=Bfdn@NEuj@REc_##9;tQl~(vzOpqvO=lRRn|pW zg?$&35$%@{^l4Pnn?K#U%vE32-K(mCP<9-;e~S2u1n32#bzo``c%G996@fWj488iC zK+(ocg5AZaH}HD>v%j)lxhcpvOj)RZMH}Oe<;X)@E{|E++SZB^VADuRUHEw?mj0_j z1+tsDhL6;QnDlU6OD?yVlISkU18aC zcw#shF!&EHr>XHTpg%?aAUQcRXPp#ME9@QS^xYpzGuAx3RPtR7{-97BJrAr&Y0}eJ z;VhT4467jc_5;E0@|Q+O!oMIhpZYngzVbE&C|)hm-WXvBqRw#q(0W%@ucdQn_FXuj z^*}_1+G5#SCnNRp?M^sT`b=-uoiO$1nTsJ{jEY8|PU#v*v3K9HHzBF!grh?|+E_jg z=Z3Wj4F)K8B5*6xqgCYwR(l7Oz5{_i{S#?o(APre?4uh6XHbGE6&E*a0hrJ^$R%!% zpkVdaXK}()4OSFsmq-b#KFSn-lfWzJ1k+fmF3UtY!rj`!HeC_!Y(CydFpXs*3il&D z12RLGy8U5}js!Z?UPoUnrQH}4L;XC_qTuIuwk&@>8R~8v)rclCDBHQa2tjR)N5cG# zofG8qyDdG=(Vqm`PVKq*WW{${4&_!i*4h@=897mZ^g~5&Z=iV} z3;gX|W(3K4A57|qj6k=R8}Sn@Enq5ktt|;_;<{F5IuTk){mrsr*ahuuu!F_&2Mey6 zTHoP=ND;TRn^*FHF(hKvFUM?G)s`of#kC}`G>hvo3?Ek8HUI}JClGw86kC7-$FRk{ zW@f1At*W$rLe2~=D~314bNY32(E6ep+y~Wijz32B9mo{k_lI?=0!!W(0J0C*012`P zs3BpQk!RCe!t^XA)uMYKkKgmNB{)lJS)8EaFgYup+^&(|aXQu|2Z&k(MAcv|q8*aG zQUWIaa2^arHz_x*|KRFWvucgjHappCyKE2c^7 zcAqrUYXP1lBFuS&R=+mi#m_}q0YeC_C11)v{Z%lw#>9xZt~*ze^39VUhLJ8WeYD%{ z+oEbN1$w-3@>5@ae?#eeL4$qOUI^pB8J1K5iF9wMZ_zZ=+fF0C@@2vKU>WwiibN-E zzW~?9%K%~EX zgy3IF@uYyM>*zD6yFWGgR!7)c794@1OFf*{T{dbY6!jKP;Xf7gl371HF)Hth>Ysew z4x1=V@767vw;GA?PYcMuDqq9TuCtnkRgDN(1HHU|AAwZHZP919=ofM512uJrx-}!p>xW zUwcuGUfR343m@GOS5Sll&oN$!RyKKr^<>-5hK|v(!t>t!+4vp9??VP+kOV?-y1TW{ zorT4y6kKU=1wG*#oW)oWZGrIa#!#P(=@X6WY1xR4{9uxK^l6>|u_|*Y&$p9@hI!)m z`~u@Y3=-6!7-2qUp0DkY13JCWj`+h>)m&$1{ zz9KT%$ayMMzs{E0+NSsX3qCcGT5Lh>jfIoSxf~A8yADmby0mZ;+8>>!fvDG)u5cmt$+rgp#PbBupc0*mHGlz@nVp4`@BD|upuXJb4{NGwBUR)z zwI?vD6@a>JQ`qNM_3XlfH$}3BDsS7;`@1R0_^q$3CQ}!F)d^^D*0w$r#bag-ma{WS z2&y@eVn&9J67Xj_TPg+3Bt)$0%4P{9u4ai=hdYwEUXO!#CUeNNi-^(FY;8jY7=Dwg zqLk06Lia_6m!J;~sS7<}#2J9Z#HL*1+QN+J)$IAGXomEQ|10HVZj_(nA8POB8T5;N zSJ&#JZRhc9X@jUD$&;5En2-Fz$vs@xE+rBtE2;_54|DIKn8ex+>gk_eQ7q&A%Wh@p zbf0rAQsETFqAXRz#)17|a!EyPtaQG0W~djvQcTWdX~4=CY8DaWcyQ8FwQTLC;KuExK?8gU0gJifAE01!VSc^R5sxdEXTvKUZ16@H8^$ z&Pk{af^5%vR#y94(d?nc9k}mIt|z(VwWT3BQL`w4hBd%{qfn`d(!8E&`hT5vj-ON~ zu?u@mPq<^9rRI0*Dwq6u=b~6<<*zlPZXVd0h?%eRYxUm{#xV2gzbP%^i_z*{0v~d6 z@~#qdL^g+?hfO!nmI_99>^<@cOsAQgKaWDQ8Lihs0t z+dtxs-*rt6g z+Y&VBYe^LpM5=j|&r}B>Iic9@2qnRaW_k65J-!L?$0cZ4RDtvc6EuopXvT+1D{(m9 zBXT2cAGZh6=-B=c#ns%M!3rf_bWJbbJ&)Jk&mU+QT+__rnJt5ulLMEBsX`??xDC!o zg$(zy|8q}3uiZ( zuWTAn+OS2|!*`|j1g$~3ng5qIx6c2w$=$6Ij-J$`Tb;{LB|No4Sf9@ zqdS{3&9v5tIz(ju+WNqEW;lK3i*b#zlKi1}Q+nn{49tX_jt~pD<`31`#VL<}Gf3#B z??V+pPXS5Tl2YgB2Jf`yzCPYvY8$%ci3}WKQI)Ykf%Sl5LI8R-2s9oZYgPo8Z*lrD zTFnb>PKa9eOPj82Xj5ri8oaYNq9I?;3umEc^5l2d%ubLI1ztY=V7s;p^G(|lYwLL< zJiSxR!$m9U1eRq?eK8pOiM<#Tf1@g?M`FD%U0JI~t%l&#ptpYWA!a^Zik?f~6<|K* zl=C4`z*DOty^Z~Q>~6mA@CarQ*8Jf^%B1ADC5!aeY=>7cm@@{ZBDh@oi`ESGjPF(Z zfKMAuwOrGJ%a$%t>UH3##h__T7Khl? z8EM#)_tglJLS&K9LLJOKC7m>a zUa^wBzlmMfu>91{1_8%dauy3c8VTWcmEt>E&;h#X8~!;Q(^b66<92E^+GxH964Z4# z-dgytu61l>XMP{%^kh==l3;fkKbBL9CgjMVJ$;G7%Rv^}+KY{KjRpH9*9%=XJ&*-f z0cykTq#UUa64!F=oCCzKI9jvkK4aZRlK?~}I_#5x6HAl6j``>Lx`Jvio zotyNIDJlht%$i1=@t>zjTXga0TaPMHRy^=FpGI8^byA23;t-L+KXwTNlwG*w*R8<= z4tb#kAs$*Sxoyk^**40mJD5*F2VP`3kXK@_r$j0%JrMn(Swux?c@QkHz`Q~{T>SQg z&r4I@gO);R;FHh(Z3gp z-L1d4*;*PTi3`ezRs;lb+l1hPB3Vq$&4|>ccbj||HBihtO2_+X_cHz-DFSIVB9+ZT ziShm21kS~LY0mk?Cf!dcl)vh@B;6B-ZuFFtl&)Tbizt(?gMQRGCS(?>xqa0Jxi*fz zx=C}dD1ur|l07degi9pUV&;NNLjv3bO|{ynJwK1S3{6uD++~{X<4J2u8G5vnNCV%< zM`!O`8m3^kVZA{E?Sa}LOfwg4Hz|wN6c(wX@#t0<`Gtgt@BPlQN=OQ+gffS~M4E`z z-imc=2s6QHB;?mRY7!9mPdx^fTLl!5GPM;tXA*ab(n zhFKc;k2p`?DXT3do{Gg*vj5&f9=^a8d2#?pWW2|LYML!qd;PaPV9HbvOH&!RR9oSB zGMq1G&BZnM0XoclVE*&vuyNG!d0M~BQj>w#!JAyI!-D+FU)@*p)7#bu7X?~e@4V2eiR-;n2yP7$vbMGCd;Yx}=r5bHp#nzXWihr&y zDRN2>OR9H&aGYNIH!UonEx1n7WUXXg2^kD)zu^zY52`I4>W2KZ28NPBuyHAjF%2Wg$;{ZhzVE?l2k_sfiUrS%(sVYnD$#ExMeaffKBSU?IT z-UL^2zpnOq74w1sY}0Z0j_;DjxRf&nyLW%SI^eCOhZe5S>FGC5^n+K-e+Fk{%_VVh z#jAiZ1?yLWS{+rmVOh}iGAYITVNrdv`2HRInNHsHhlvT$#X1Q6H=}&56pv$=*XYOV zOXv?T2%ixdicp2BWK*|5SLJ733+VGfR{t>ZEBIpVq^za&2F8O6Y|dXHJtCNOSXU$V ztB@F5U+VFt(W_o`HsXjuatZ#DJkO@PF_1aK`! zc3;|G(1LUUDx{nBV!+dq&7givc|o4EcrwtvbF-tPgO9)Lx1fLk2q`?CpqYw_Y76g2 za-5_X?O*3n;p^W34ZYD7?%Pjvo>U*?U0A%Mq@hE`RdIEU;AtULIkt>aan3)2VY*4 zum9>#0k#uT6tC@kwc{?BnH~`b=tzkL$-{M%V#3?L^sK3Tl#&M>}|yCsJUqybGrZpbF$^A!=gbaZUYJFZ)83#%eeur-Eeagbhb+ zO$k`7ikV)xcVN4Dg3t&_91&F;`hdsr5M+n9@miyBT+1(pnxJ8!@aEgCUs)5y+`PQb zfMFn9JPq3@Tsro4hPOz8m`a0Zv75{uQ|ehyZ<}EHEPMofD%6m z8n8fp@WP9JpUT(7#$UEQd&*-4UFNnO5f|37yrxU>sB}>RE+y}burLkxVFqY(65(LAf5Q-u_wng z{nB0~$DUN<3&T7$Rrp(!_eoQsxl4+BtNrSxW-;|b%{+4@!J=BPw0i$E9W@Rr|8U)) zLygT|m%9_}GMUZyA!$UVN4L+a&Q76&amzL;Scvl|O>3@+&Ee9RU;s9qZxT6-O8Zl= zrMe1X=<8;(eUXuGNG0J7I6uBmVGSze*7?hLV=mh54Diu^2b!$_h8C|YtEfw{(<@*9 z&7?t1f6eyC`08ZHm@}AKR3+RiBAtuiGt_~RhO!MxQLU&zlkmYZ#n0}6sXoqM*6#<8 z{Kpt``I7ZJM91Ura^NTUF{Q+WVZ9W_(xX!WGd(pT!&R%mKj#8TCWZmR9vM((5Dl7= zu_;oNSX`Wn0QzqUo-OA3*Zvtk^n?yeoi}2d$ml-JBw$}o{u+Z|dlL}EGG+`EJ~DDF zChWQy!jz82Xi^&ZP^wp>AcLq9&@vzrHl8@Ra)y+X38G=Sel7grDRbIN&8vU+T=J>kQ^8A zk!B_2QSAs37@C*n=F0^aWkt`D-{hK{3DT!cUoJ zEei6V;%|{|0nGyO)T;Du?1<@|tm1#^92SRaFq3jB{|+)r)xrckU_Jczl`|^(HP!05 z`uF~jQKj)6%+Wx9+72RYII>2JsTmBV8f3L}!U#e?aPU;>ftFNp_E(IvzzI(vv$j)5 z`iLYaS>xnl=-nvN-*#>_bWQ}=3pP@Y^_xM9kkEfYVSOvQeq-e0NcO(>U(pPEhVkb& zrb!+uGE5a&a{0emR?toxa77>9dR%tvC0(#)@XA4rn7f|(Ll3WFVtA(eYkwJ2L;Ld;uKqpn%GtnI8-Kg z>K|OmeNPtB)8}IDEujsZV(LXO+;&~p!+7a@PPp-Hoq~Z*7#8?C%*R@O?j-#EL%VTN zi~aMIfgo$6l(HLza^r9|d9{k1USz%H{`rYX8EJ0MuVLNr?@)dsx zx6L!mOC?2}tI@?Pe;X8gRJW(x1Y; zEo+*$&v?&wxiwFZJs@KL@A8$N+wOKTZoTs^3JN8|S}LMhqVu_-?Oj(db<0A9N5QYs zNm{%Rx3$vmCjaoHW0M${`rl4n!eJU~a&cGasX*TDk|;y9#LV35cI2XjzU_gLHa-&Cbn9YVuQI#B;)naT-WPzpWE_K~ zC2AVuhj&UtGRx#m&SD>}l$EwPa-Ba??pye9`TcI>Irya}_xE>UgwT|Ok)ifen?6#iS`sa(JCGYI`}h%>n4O_MnKWteNzz_3%i(=RkHp1V`ou*|_1>Uw4~%6S z1dy+s)Pb_@788otgXB@Pjc@S=UNfQ?HHkubar^6z$K_K$_O40$kQ0-^n{MIT!U+-D z8ree8agAiNrX@1+SQn2%@1^$o&E?3;(7UzMnDwW_+ApzP|GuW{9R1U0@k=WHeWn8E zd{caC=l`u6KZcUN$AD7M-j;x0ij@906D&*#@+RiwcaO2qyEEyw5r;P zD@)+gBm9dh-C!p*qT{NUS65|MYA)R%)pT9j`}L#mm7ihBlg6w$|oTesl6vl>1O1`_v*!%TkJ*YN+QWAbo1i> z&+T&{GxON{p*1U1x%&d|T#ly2;H~;&#_C&OWTd!63&dd8xUY*`ihMPdN4psnbmMA1 zN|FC7(3!Aa(vOXlANjgIrZS}YuX3vA@N$U@CupTxUJ|e{wZn(~g6&f*Jsalmk69Bh z2uRmj+%_`Jk1vqNyjRH!r)engQJ34%Upjl8$NAC$^cTfXVLm2s3h#T5s;ap_a)h3N z444UgU^0TdlyLMA;+))Rs}nX_RYJ?;0}V5x5WNXZLva}FD7?Y*iu(=v zJ3oVZ1qeK~L(krND-}wYXJ_yJ{ivnUAeI!jFrQ`-^`(pbg9@$L9+<~P_fGD|h8dVX zu5v0tVnp31Ay>(yC$M%*DfX4TeRvD6uSz6_s`^I%ggQ1oXR50_m$LbmL2riV)f^}! z_xtI0E8lbq1j7)-z&sFzFbV{8q9KlURRn-YnSemb;t&7OVR;59|=8xxzGmb( zNL#!QOzj^)%P0Z2Hm>e#`^K-Za6O8+z+HN=T}o^JGNZH7zx+uIo2ZOCnE4!ehJ!X> zU4}!-y!B!E`-1TP%voSNg}m_>rkk6`V{ht912@46q-`-gn=;rNR7St>%vGQb9X1!= zpF;Ys2nFrWsoHp+KZWedue5UG`a?y-GyIuOG<%>U?mxe=T^JhF$e>@r2f&FzYodrc z8It~saCZ$k0SYbMlMqZ54*^6%c4{oKPECoC1db)@*c%oSp~NKCN1l6p2voHCW6H90 z&8{vLA;!APWKV1d2gtfuuf^QMhE*rT7J{4ruO(yXG_BcAw*{GH_M*RY@JSY9ui+OH zQy^gBkDarBERsMqVqqpFpY$(rE#-?jfkU=jZS$K3@1}5Nf{-^kn+<^m{@$(78{)z4 z?v3{NYS_W(tgDJCH>G?t0<{FRJk(FoOpt{Ufhzmvi{-Acx>+HY<{j1)UHk=RpoRx= zV)wa*x}H&LV=`UI58Ab;7^0ULQ+u#eWY>7W`A0nYeg=vQDX9*DtZXrM8nk2+RJBpT zz3`LQG%|BcSa9|b8h9bXF!*|`bVIM(%^N78NM1RJnLSat311@fPBpta^pyJr z*B#Tfsv%S((#&98Y*Qk38XRxr_z6BgeKuof?cHMt4Ey9R*(xNKl4P%GG}gGJER#RZ zy=a(BB!q3IF-WR3?SeB~GDGq1i0Ct}b`Oj9;^l|ZmVF#!ob9Gif9CfJ0qR_EaIEX6 zPoF^y7@?$m*Tq#M;Qi0cAn7oob6h+P?RfZPH8;g(&;~IQYB5LS4joPfo;tiSSK)vJ z8_b72VLt4&&i!<1GR01)cS4cK_9p=|8B|!Ri=r5Q)TToi~&-8^oc74OO1bJ zU^VyPu2f4yvvkrYdnvG{=zlnS%c!d2cU^nYEl5a+gh+RHgLJP&mxOe8mwz(}fc=tGajC0P1^Tja~aln!_=WjmGbzgUXK;1tdfdGb_mO;w_`su|t z!t2Ef@3a2Qlst{|=cj{rp@H!EBWhgv>>GTbFFzoiefOI zNT-hccUu1jW#d&%LU>S}C31%ogrmc^o{9>IDSrf+&U2*H(WF(uL(s`$>1v^z#6jt= zt&M03#&4sKL;TBCSqZs0px2KN^|zw!q#GTmne6pk=Pkq5+8 z9=aWVxcCB8qQIha^WLut%5qnpYN+km%6M@8dYt{ni24O5R$@6OKf+xSOy)IB=lR~J zB?~Z{cnPiwUPHZIO&aHtw{eymvZltmoeTt;j+O7?$U(Ko<}ci9)Aww+Kj~W){O6A)77a2tAGi>E&6a%JZj%dQ2)}k zV6*l$070XC7-LvTdDuF!g1!P~DNmNEfa!LCQ#woUL zQQQu!oLIXoah22Y{RRp{TeHI5Ok@=5%;93(mUH@GE{BY7ihILB`-XB`S@Nq}(?43>w$Y4qYQC6#) zh6WZG=b^o0UQC~gaP8B`ye@$;%}aC%KPpa5ob+#cXl_ou+;c5fGyPu0{L#wMTUv^< z|DP4rh1i*}eZD!m&5(HSe%V^W%SSs~uk+;2Gj`1PJdOioD5|!G-#kI$T1C9SEqZf* zPKPq4{j15@trLXz!Y#ZCKe^o&R8fvJ(5A?)va1;V0~C=W@N;0 zr4{cvbVa2XQu9wfE@v%ld^Xeb(u$eD*FA!N2g~ga<9PpoD|_E=ZTWY%NHs zS;^aT1Ag$CgCo~=Cbo?Issq^uUaWm;9&gOD54ZK|6uMnO^(4pn=0t>rCM9`TL)wP= z%H(~o8nsnKgl(kdZ6&Yi?fr?sb;&_nyW`&!VJC<4{)B@}%MWcX_5<{zq!vqpT+XM; z^Yb$V#FpaVNyNzXrVZmO#4EL$J;Q0*81zoaJVP1X@(WFQGP6$sHa6;c#gpvy)&S4a zgGl5TlOkW=lpqCpedO?VE50X4F#?>w?uJ%$&cih_A?+SR)l$r#s!I~`LwC}c zh3215Ob?PMBNF8&u(EgS`<4PFg-%ws!bLtx`0{00RvK-Xefyc>wU4CnsQ2ANd6saU z7#X3KhXok4jXvX1E}5KZR?{$2O)MKPeSIcfX*)XhYS62yNm%x}DU7sjF>if7#IO9f z{|;liwsu5^XERFpShMo0qP!>i6=R0?)YBVEa6AtuJr^CEWr)`TtiLaoG({FtNWJUwO(VtLPH}M zakJ?V@$p)>rHh_J@Uw(|e>r%0>e4vLG8f|AZF`o#*&hj9>{}}7EAy6|9B;AQBOkK# zpmtc)ZQZEJUnEW$4rz7a$dV5K%QT;ACN$EPz3C!U(|iy=Q)wr{diVB=!nNpEfjDq< zNPgIUCH=eL>dK+b;Jn)ldZ5iPi~lQg0bH2E@Q2h-J}Mh1`{HVi-{_v=oK>}|ToyOQ z^D-Kq`p-8;JvMT;j$=!gzH&SNT|lyHs$EQ-bDdBL&Ej^S!<${68ItC(bZ&^Gj7Unz zGrld9hLdiI6P|DLRsA*yp&G@O%Q(Zq_8&0^8ymzApkb&Eh`f}q+%w8Lg7R>)qEX_V z>N`j^_t9Lyy30O0PJMu__Q~6w74yWS7z&a1Fk@3Y8q>dKZ{(VS-{$VX>PTupIMii~Z2M|j zwtusEtclQRzc4>`F|WoIG@b+UlcIg{{b5!!zEzSpNYt^Zl1U|%9uub+D!S@7#i?dT z3#S_yBO#%gd;V#SH_aU7L?840(8|lK{*H$!1fjkA#m^J}bSIhCMysXjUhn~L5=l`- ze|p1;85c&{ThuDfOztLHk|OV|NG~e19q@EgF@KVomX7i~uhYmyT=LzuPDiE}A8*xr z4=+aMTins}IqC~H5CEPEfqIw<%ESfaSKH^BH#(1TA6mVcKpVT$pC~D1EN0f?6-vR^ zs!ik^JG7FJA9tanALv*QaTUUX^k&@pvFxP^=(z9Gp|p*^QNB_pWaspN5rejpZyY|A z+|yK%Q1IY?5J~8H@uQ~3&h5;?;sfPo^vp!duA=K7r&-%NRn?NF&7wjrd?uYDt4Z_H zunTuJZCfXc#Yh|Z5d7b^D%Uhxl7iFe---l2$=)(seSPPF-zPhYv4*||lY_RexMw>LI?r#i@r<%QxdGD;(& z(&YDB13$jZ$#u?#oz*R8TgzfpN*Py01SG8c#plTOs<3W+kq^#C911F3%zD%c0yj|e zmuRUd==(Dy5Xj#ee{|tQqupHI%levQX-Rah#t$|q zp|qg!51cR<(o=XVFs&)=k$WRr3K>q3y>C`dG?;`!;`ejaheGz_=q~kgD!XtYw;DD9 zP#j%~dV?#d@u!f-?dnuZhEZs(309@LPkCy8f-R}=_rl08B-8s9d@8fqgzHz$%IVES z9zb=9vN#PQV&_C=}b6J=aRmh zk!o~_$@ zOqS2mMPKGDcg2dS=no$!fT_ZslHdIiVBrDkp444^FVa@>?W}raXZQf^n}v6I4VCk> zy4AaF-lMunbA$dp$jrbq&`7rdtWVz-ZC_PB?^o_B-U97(YT)>cS9JEZd9s;<1}x!Z z9c5UcqOeVyFZ;Xsr0oGfa_t|Es_93a<+h_W+39!iF+Tv#EQGot8ETgyM|smFULa8 zUiH6II6rY)ps?>Qstk^_3;0<4MYuaIU(32Wg+%i&Q987BHT`;k$X*;Eo=fYLExaGd zdXzc61k%s=L|v(NEoXlW052EfN395PzcYNlv)H7TZ#XA_7Y^6}+poX=L+tJ5v>J}D zc~=E)YeBED>gJneFTYJGUx^H)`8(j12i7RxA{lF^>c>u}OrFK)+(!C@u376wAf@Vn zIBqP>*H&vkzU>6=xPd=k^@N+QmFk!=XA7KZE@KYHa7C4i6xAT6W2-9MroTYAnF0%x zhE8^IKXl{9^pMSdMDZ!Wv177dV(S~tGW>FiQPzc>QT>T99S4V`xEk1f#~c&`>ti5o z-h1W&$tngC>VXEUAGCij$O{6RdhY>MSdebpa#H)_)*J?Wlr;+hK>|XE&FS&$f*g_) zXGzrm=N0(v#Pn6JqL=OWf7L~SR$lumy#Tvaj2g|S59ME?8f-sk^j~K^?_~u( zzjhm%GVNSaMDeUgKkr6s9>2bdAYHE27Qfq2KWQ(~?H!_in4cH{od7a$bKLe|tDAJX z^-7=*qr?L6KzYm=0DiMC=zGYmSaXilG!K~wiP7EczYe5agg-~(%_et0kmoZ{E)rU; zmIhQOW+vu_O-{luOe5#qna+Q%SBjTR?YG6!PL~g|P(A!Ull*r7xp9T`c>orxNzqFK zZ%{}#d16v4_L?e<5Q`t|0&{e+1DiZ0OSJ0^6cTK<{_H|ChmBGV2sZfP_ZN^`H_f&x zb~7~})<{($_vt@`OMjA5JrHadhuF?FFUvWF0H+UKE5yPsY#$in=;QNI7TL* z0Yqc1E%n+UM@Z#$+KKc60N40g_^Z!hS+`-p|#)|yw7DO7FlZlprZf88^n$Bg!z**)EyP@8;z+Ev@UN*oCH4! zztO+pe=Wv{kaWMX-oO5l_rv`Uh^Pca+H+48q7igpfTGi77md>^ z(L61!q!o;~v|IqGGk}p2fv{|`XWb10t$zpzykWe9zC_)bV_Wl7@)(yeIY4;LJyTzV z)P&-dc~OU0Y0!>aNLfel7HxQXf=sgZz+U-7GJ+vHk!)0ge4(*+SE9E;Mp>+@l$Fjq&*Q|=_Uf1w(`dv63! zd#Oo%-R(Wv>yJ84nhLE*5P+w6Y3yd2d8D65=bu0JVzh;x*rU7ppgdmc0cH%gw%*&o)alpBl=8WQCTf5h~V31}BNH zNcnX8Vq%Q(ZGVNeSkA<1yLH$II(R%q7NuYBPe&v*=#HDM#hceV^Izw8y|DA~5p5iq zaz%1Uu*&X@i(vkXQ}aFS^F`02wp$AsgIt4>fG^Px4LYbnVjR7hr*TMa*J(t2_USiF zVR|n?HpU?we03I0Cd!JSvH3*sI1Ubsa&lJW1_*I z2#JHYAA>@|23mrq=#te%O)B2eVDFut3Ql;osAm@GrAoT=4dRK5+xeUU`JSxti~D8@ zX1aqfF9J2f{oS|`>~t4$`9gu6DljZp$G)-8dd!+{_k(p*-6%|(i5K^YD4qo07UE18 zcSS2>?)*R_RI?Z9h{$M6`_AVHlzmjPEgPk_IO5(@arEFIE7J00&1OCP&Z3x#$6-~Y zbJXY3(#QJ)e-W%G)ro>NRQC!|cjvGgV;lb-0I-(!(YXIXmOmYqvZ&&r znRc$M7BZ~dCy*uz7LKeWFth+-HX{i78kPEtvO`zmb`C#T7l8x|%5)&l%i~2DIz{5D z-Sf6xyyuQsV_-{$t6R#jfpmE)?#>MAJFHRB4l!LY(P2g#)&8oXjidKP?AIeh*yumh zsUpVZd%Py&MMaI~51h)|YNVnG!G`n(G-MX1+VZhw`>|h_+=K_4BRdlhggLE0^OYE# zsD#42{m0|(>rWtpl!WVB#6Bu8sn7@4h(%UFMhAn@=8N@?k;LcDl-Y|AQ5`ys#ooas z4b5~*r%#0T!~A=K-|4pGRJzm(_~Gwpofyix20XRxIM@V4H|BTfmZ1(aj|xqS(VeMv z@?B~1L|CjXq(=;8HViU!C?RM%1uLr%>X;&}LQVF!oc83#nqKe4Fjm8FgfG~I^Qc1y zbBOX&ht;GN3QZBABTJ0qD8r~e0vPpjs=-nUbu!%eY_KW*}nBS2aikp*@s+xoQ{e88 z8&C~F;GHq;Hf5=Lc(sEXGKrw8I)NGOaW%t(B04}(Mofm7f8hVg!jst78y4J)u?tHi zfDmi)lM})81@FI$*23F)aG4jmbI)GTx1ZBnGL^$T#3N6kuj&8sKRZbr-7m* zSkL+{v#fh8P^#olIzB?|KSKaF~Pje^wS8V1s>@5RO;t->v=CWt^gk(Li9VP4V7QPPnend8H(`WNYp}Tj?lu(~$Oq zzhxIpXoxuEU^~|aM?=LaXz5V6$bAH7%M;4WmJj8x&1C<2`n!A%#m#-bScRe%l%;d? zel=yj`Ha-U*Xm$hj)tV2Av6&8c+1{ZIP;d73Z>%B}8P)o%_#5stm2UaMg1vk{+{k*=SaUE6lDy$Lv>Obee(#kfXn<=0( zT-CY<-s_A7q_2g*P9Kd`_%R@yT8iOD%AYRIu$$8NpvZT>=ys|)GcjzyJ5B;6;@?+$ z;wi!7I-j)fX--KGeI@HsO|;=QYhaCVO=>b`40Zny*}J=sbOgwto;vkwvjbu)*RWhm zkrrjs9kQjKbJttp>YdV^j%rFf^95k={O>aL})JBP^%Yei&9v2KJi=hz%J z9LTpH+l9xRj(_jS)~{>{NNj9)m|192e}>!^9-^-jwNZWlgoS9-g_Bdv;0YAnv$6*$ zfa)5n7@%d+tCkGVF0LI%K?3`LTL4uIBVgdYN7y~peZ1OCc7$PoX{o{K!(|7p3&7#h zp(*@X`x8DqT4b2F?=wMvR|4Nr(<%Liyc+5!QV-sCDTVV8>oXij)ynl3+*!m)PFCp(ihH1*2TK0H&QcK zgn5RKVoO%vGx3g*{#(fvh&wZS{`07f(<1;NgtAN|Qxb3|r7)Cm62egbUUiZCF(cua z|MUvq*D}eQU7?)rw`UAc+lNWi>ngw&POy8o8e~A58e6EA@q}E8t#*tFaqG*GP&8JD zFgTO4#y3C($~B9Za-fe_u(Ee6SMIn6;2g=fBD9CLP2{p=in(Xu8L@;K7G<6Zc$%lw zmp_WETp06UItU&7;Zuzr@d%ZQON$%jLM?k}!)w2S?^ zF&P!wclSTrV3|WWE(PuBXnz^k<9B!{CE;QcnM^Dh!3llAP!`K#OQV>DQS2=+f3Y*F zNvlzM@U^N1FC?wU>d3VCZ-d=0WTjv=gJ)(<>sG;EmwKw=VJ}7t0ugx(_H%-?`7)AU z2^sjajaVq(GJG>4VvndS9JCL1s}T#I{v7l*A@Yy9XSICTsY;KUnq+fPg>tA7Q+tK1 z9mS&zBuPtzpMqAMvV2!RVotlho^|$;sG4+MMREQ-HAJ>aKusshHriC#S zvX{W^aeMEl%@RUfy`Mt9yVZqb`dnFg#4~M4oIOLkLhTf8aOJOwDsPg{vBnvrqQ8OT z73SUw@-}a@dQ3qfB0`6-tmNG9*T?EIc9N&@jKj0i4Sz z^m?_Xqp(5CKt(&HJ-CbXeAn0 zphqxTxFko1SeN-Q0{?XvVqd}Ov35R5k5lP%K7#2`L>M3y6g1_5S{Vo;Gc=o^JBj4Wqfw@9GA%1PKg7nUsb&-5C|XD|{?A`< z32{?g9K=d!(DOZ=tD84@N3JNsio$PJllq#LqVQRP=-#oy3SaLzZKo|9FtZcMM3Dv z%lc7Ur19ojtmNr4uNM8@cG8xX-fhId7Ko_bR2bz$^8b&KtrxiYn$G*R7mzHH(=dA zqrEj)%VK+QS#e8k^CCHqHObx9QQ69gK>ffq@$6*cvoGk5VJTkaBW0CMsH%JKJJa@) zQ#tMSD+4Ey$~@`6o*t8SvHfLdxTk>Ashj!T!nWU;C+j=S37!JM8i5s(+f6A}_|E6_ zwVw0ein%5f{rnefesi2mgb~ghXxT4-B=#gS8vmOU^lq0BL~@ ztNQ|)ga?_$6{p`gIu2qPlYl-|2kpz%!6yPd?^^J!{q~ZY*EIQb5AZ#&kmLC_$?5Ft zCcN3F#NZQy%fc|&ZVk0VW%l07kT5L=9f~Y|^%t;HVr;!=6DFE3sZSwB0*@WEk`6yy z;jFmvInCKMo4=43lI19sAZfh@+n)ZaPHS5DF@P#4O}p7AK;u=@`q>?vvm@b5DrzKB zakjO)h&CB-CVZ})>H50-O!Sfe7qnRX$Ghz*TlLL~VnP)lGBMlnu^J}L}YleNfgbllbax!jPT&b5Z zy-j0w;JAkWp$Dsi&l9ZiF7iVKG>MM0%eMv~T{z^HR?y-tT6f?iVQ>vA54d&FhQ7XW z#9;6(OS46!Btn}Q2@L4sJg`;EI?nrgJpHJToOqt!cu9&fCI=A4E(6)!Ff*1-Yf~7P z|LmpB<~*=nj@9ryJ98gh-k!T}G4k)pbMx}jPKnQTkB5b!G(9`a+}`q3^^dEU)&n6t z*L~+NrK_s8B6^6m9*dGiIHI~X5(tgcOceVYn`Mc$z?3F*s-o2R0|pCX@Zn6A-L}7& zQ!dxJ@~Dr8-rb9>$K!Glmyy&5>C~-nR+x1UCY}Bzm<0Yvv;S9GH@Jivd`&yPkw#6qK+PnSrd|_m30b#=N0G(7Z4kTUQ8Kvc^wkMdJ7G)sjRM zO+az%<%wSvk;|AwZY#>TRKO3_uNOPdp+KaHslHIpqzN6DwYNGc2DX@GCUT>ih%yWy!Pbk!JvTrMeySfV0a--19{buRYGe9b(C ze~{&S<%5Uhdl97v-5a4}T4rZZ;Cf}MsY}FSN>Y`K;cAJZmrv#*Jl_mlSu(j}_>|>4 z8a$Z-xUiL{`#tRk#;1IqLq-6G;9m?A;;^n;7pK_2xM;c~996Gx_c(&VTJHqg@y`{4 zTsZ9-Q!#Jdj9YWt+`Ts&{hE(bHd$`cs1v7ceHM#QR(nf%X#0`pmOOScMg=a=3EY6v z7)G66^5MKvFm2=G<4C05_G?|iK*|eIg!cx>3+e-T6*E@%X($9;-EI1H@F4Q3!xNZA ziEH#ifGP0+uwF`=f5U%Rl@~3f?W!~41GHptSQv8|9# z_pu}_3r>xMoPQ(p{-?ZUzFyI2HrXAArdP{4w>(ERM4Lgg7$+BJ-LlL4$u+w*TjSue z#+KP?<6YOEd6B14+MJ2qI@;WcQ%x9nh%s z+M^qz)_(|Ch&&TlWrZH*M}bcaE87iRnmNL?1CAPOq~tC-+V7=xWR4H=Z&Sg$S9d(8 z+@giM%Ikm5s0&)_GMj^K-ObC`$K48OPR{$jX~WagrTQ+JawecT^ZqVh3cGga`scXe zv0TUmsU_mXlLXMIyVe-p2!_;x{zeH2(WA(6O?Y`!Hx;Nzteko?&W zy1 zoB=4%;3;U**ChK3IMf1FRtHs->7Oau@EWRC*%?haj@HIVM%qzt7*6r>{TGgB$_Pde zC@TIX;+hC@#8jN z(C>CF6h=WAuLX{D9t3ZSCwY2kOf%QyLVpeO18z>Aya*CF%$42Z`*aU%calA-vW!qW zxs_H4qL+pi3^pVT2-ijnQqDzHjrzlSavmjoETi zQaR~UHE^!iqRRaRv2)L%W8@#O72Kvd@y~9#W|6oh3%~o@@XvL$sos!q_zY;KGX8I9 zSn{o@FJ6OWRqITUe;65sxjQf|FybeXNSHI4VG7_XVv9~l)qF!Z_p7m z2|a*jFqnvBwJ&+MKlLwj@dJ`Yj^0WU!@$1kq-h@5{MYZzNDNk4WJF}<^$FpAt^Zz^ z=z_z|4}L*ae-%)(B7%J$&-z&Z0}rS7`xE4tlK27Q2CX+dgX}3$pY#JTbHJLCodq=+ zxHvGFDvz~wmzl+EQ^~omF36v++<`hrw=XgR!gvK&1tk%*6HWLZp9!?qD3f$ysS$?e z{``j=_5fPbRm8dlyR4kCz$E(Syr-V4%2RAO#_ zbbJJ(W~pl8#lMrIXNd%?h$!U#xqrSf^|}*g0yi?bBc(xSl?LMS2O}Cz(iel78ly6O zSH8CIS1~7AkZnrcY5ckhx454cb@C1PUlEkV=cgPI)vhw&Tpy5sUVM-(Ch%&cQ@lH< zXm>c$a|1c?tcZ%(E99tr{1FZV(j<(&AyuPQQ6BF2ZI!Ojo|4KlR)tA&89=EE{6SugiM)5ou;wrv~Q}C}_(Y4e`jH7B!DJpgh-%CwWD>^_9w|L({!VQLCa#10mi0SpfM;pXcRIIdPSNE@{h~^x6p9lz3PXP+?&U`^oipk zZEeMEST%#dX@00T_q&#tiuM_wF%b~`|A87VA@WzvnNxNKGZf{9!*nn`%p3j>YFO({ zZ+4*O$soX``zOFDMi4V`72bWjIilvgJpG3sUBM52HbL$v<6n4DaIbGeZ_Sgl!^!qF z%q|XNdx|UZ+q%X~mZum$#`D8VQq2$~V(3z~#O|8=0uS4Yb~ZZGupsRHL}^nHGxFT5pF zw0!>dar4COSCegXK&8OV-Brnr+F2AsN!U9Z(0N4~f!kG~SqTYYSoo-$r{STf!8;>$ zo%cQGg3?qJM;TA{sF$o4#Cd)RI4-!JAZ}Oqy z9c^@q-t|^;GI3+L-#EcSVrclZRyX~N`Oi4@sQ;%n}rBUP#MlJ6`{ZB9L$TRRhB!Ag1kVa)(Y zrJBg~lDPU_$%fCIkF)7)-cN2M4^u8H2EVt5vwrh+=V6u!muxd>{$xD1=DDf+ zi4b%g^}f=QauW_Wa*Dr@`2N{>^5;Zt@u&P^&)gC}i{D7S!nURU&fN0mfy(@!%Td2; zDpSCfa+n*Pw-}ae=0<&T-pJFu5;>om+h+E&8=%+sP=DHH>?3K7=_yo?CCRjFyEVCK zPbxP^WYA`l5%Q0ch};VL=PK=b+_jYZ4Hl%o_o8(=cII0eA|rGoz2A7!-%zD z>YxWaJ_*Pv#M#!kmubeo!?8H2wq<{bwp($%XXm^_u+5tzW0_cO9W&>k<*N zKd-gJNbJ~0>Q<&9M@=Oda-XOuwC@{=O(&b4iuXPNhO;}v21Xnr4f&pI)FrV7(8BUx zgQk!_Iu(xvi&3?4?}O`GV{26Z#&8Xeym^?!nmIYR@^CV{$+p47#Mhw_fuJ+ddH(&W z_=LeMq^YRc}xhy>H?KtN1lyW?sfzS}$tQM_x7hag>F+CxkIDM|T{_D4ApQ%g( zFIx(R*MYgvPuw)U8qQJgbRW@y18)--;lPn%?ojympqHwS z@phs;Sbe5`d$*^s69H}U1M%4NW3IwVJOgdZM3n44ToFy>{#iYKIOtPbcKtxx{xj^L zMw}N+D!n+L zUbTk2dci*+FiM$^%IgI8PF=oGf2g%}DVE~|gToTew4uSpN$_mJw0W_V8__H7=&PVh zoK7vrs3nKUQIqyUuj2wi?pbZ1tWV;mNM7+>>dSA-M|vdaX>lr{-+h3JOW{%>_OO+9 zd)Pqj7oC4rEEsor^&HGiaT#a->fe{ggP}}!B^EQmLo<5|91E7~*30pUi@FQ0#_!|S zBr9~{1!dJ$lsKu^XfeZ7+qz|eJh4)aWy6SIOP5$gf$n6 zsqE+3Qe1R*+epgEf=m}Ty6L^MpSwX7=UJKEFMO?f>S82N&P|i1+ATLhaA;&$a7$`h ztm*(B_9ajwFX=pA-M^+@F_U)js)R%U5%a!Z1BAa09t&iX$>Y<49xz2LU-r?NazYr&&haH z+=!y7qgWI7?D%ed6WU1xP(gxcLH3D*c0&%8PNj;E1l7$$29nbdQ{Cwvlb1!+qP*f?)Xc%f zg?w{;J`oos3_i~^Hzvg~(aXn?*}WVQ2)?Wlp5VWa!dY*zp2yu%>8AWk58&;5*QPy_ zj4Yk+c~O^c_~gaWgM3 zT`*PR>Jjj?s37*7PZL89aA8=1=O(GExs771#JsXzU%r~L5B@lNbj6RXF7Po@LNguj zL=Iw7t(}bOpP>4L6#vW!BJ~;M27x1s%46JEtqH#$t+y1lrI?z2YIDOS!J3@J13@va z@vaD_B7zS6;K#bnpfVVw;82nkQ$Dp;Atm1Vl*D>{wl$NANY{yv0(9Z|C^*(`7h_cQ z!(olEJ!TM}0{^satFmYtPZtt8ABky>J6AGVnNQre1&(j8?b zAb4MWfg%WVktd)JRXiV$%KfN*b{TlinV9rwcHA1&Xx)bxrgx~ELQyq`;a2iX=(;)H zk9~Ht8asNWU8l7Z&Mc)7w!_h!jseNZO^K4vzLejkl<4Q{$4#Z@Pa@txc2h1Rl+*9E z(zd|hz5u{a!*R%K|C^qrJZ^vS{oDq;K0x!)%L4!#2Tdom`vCwg%z+4Wtt4z90JcQ! zz74Z+e@AL+>%BUPnQXbEx$WlhKPmz0)sobt5D^f|HPWuE6V$lEhRGQbP!?fUrs6|QH_+|OO)$1 zUjv#9_>-~00v}<3hb_Jq!8^q4K-ka+C}U%8tVq+K&JLP772I>2tlJ)-02vut^A~ib z)4G+YBXrw|iRv2Mi++0=DvW+wuG4S~NGWetUj4}jdMB{1emicyNW%z_-@lBb1ryKy zW6@U2Bbg$82kKv^tEJ_8N~G7ep&c7NEifE`%yjt%I22FqaVIVz<7Q1 zLq1hSY!Oed2AnaYAfqHsQ4vaA>07ajp_)j`ESd<8pG#zQJSm8i`Ezf}St+KT9NL8+ z;}FQ4Gp;M>;(Z!f3W{n!9Vu|JlereBa{nI9LfZw?TV!7V1>DM(g~a^+RD+ESaOiQ> zSDZjwG*I}=hXG)&Lv8m!tq4#~{<29eT#`AF-Uy7V03y*3$b!Rdk97jP6vk%BBq#a} zP;=uwnYQc=H+*Y^mL2`$2WYJQ zN~axfP199JkEFO9TdhW{cn}xP{VOq0@C-Tl2CM*_Y~+?~VQAw1_xx(%=l{X4K1>#( zrgZ71nNFY$Xpy)gEG$#`?}T!diddSZKWR0vYr3kFy28IXBACXS-xtyZOELyz&bD3G zD+^oPKq&`RR?*c7M8ij~egjZ$cF-Ho?)S?b+S%_HE?;ZH0ZMzork8++>JYpB2@o?O zZWGY12;y{E&WCw`1=Z>e6uCG}5Lj34M%;3TR)Dv}YyZ_F{?ij)r8`2>C7_{=Aie9C z5;<*u9BRk?+!yh$(SZVgU~kN9xbY)YcX<168guLAL?4M4y7U&VM%WGz?Dse(cY!88 zyV@+?u<%|@iB~+i_St;E5PA^-qnR#E1t;i7FvH3sE{d`R|51D2Ns0%n6fsPlkr?m? zv583cMRpF`*GtWab=;P7LQVZGcW$R+R=^vo33ckDt(0i&qs^&RJEoIH%u2_I6R*_>C85XD)pPGP*(A)y zd&5jd=vNS!x!|8gG`y1U_jS_CFwk;ef?}}EbSuL2j`H;2ed1N0E2&>!>W1&VySbHp z1cH}sg6PSD<=QVZoj=7Bnp06vuNc|)8Fa-?&8=yb4jdjzA42O`{^wBO&sCPmf3!az zwEF_(J^+b&5{&pfDg1=v>kYC^<)l7WrY(fH%8wwNgJjdCGq9RUxs=hLBUf%Q)=@=7 zmIDuG4g3W0;h?Z3*(^=Mzci=E#S}Ofg9VGF|}W zH5K8@$ScY_U;xaJw4!N&r@N2>s%0$$Dxn}+%&7Yx9kjEWQ})77O`M@5_3INlCwju3 zFTZT9V%LDIDBe|*KCu4CYzclZrZEo( zyKeFlY;cQU3Qv|@3+1mR*P)K{?}g{h0A{ue1K7LUub&pujjB%1_?+%EBI;2jGy7T` z4tUJ%U@UV|gwJq98Y3EG=ii8PJhQ69XUT=y7prhV}12L=$K+zco2dfIV&a1mX&P0cC zt!RMbVqe9@+vXut>&g-!wSl9MT|IM2T+@HwbNI^u&Q$2?Em#Zr*Lg5(EMjHvrvWIF z#f(owe#;_(^>6(Z(l7tPNC6KaI2(t1BSbqXJ|7Ta|qaao)eg=A0e3BE-(td6WC z{U#al%1~dt&b8nUnpd7|<vFQYAV3#jwrkyZ-296PS!_VyV>STauT0EG`p7=%NI#x^ER(=(prD z+j+I>{B5$96z3D`wV3`N!}?7KZ{925J}+B5eS06q3+el+Kq)k&ldZg4MhFth#?T+o zS}!{9yzlWSOx$eCBu+EwknL;8FkToQFm81Db6qPwkQugX&HvUR1pM+Dy?I2xAnL zyWu2lt#U|^kbcI{`H9$c7#Pz2r-1-dP5qBeVyMEI8rh9f1P`Mw!q24R03DE?iY!W zRHulkoDH#;!~W`!jT*G|>L(A~br!+8+>B-6G}K7g5?#~MC7_9pgw>=j+y_pXe(g_3 zcJ06s?VVol$AAp{n<-!$@&dd$H3+bTuB)RNsm-S{kP@o;2*?SR3T>+fOnI#KCbglY^lX z%vt`Me@FmQl}iMq{3?%H8s)s4+o9wv{?CSOIig>C*X#xq1yrI)K0UhU66 zU@6D*w+@T9CVlA2umizTiErYc=i!uu8{R&gb z^Y3zQF5?S)nzi*skw3hZh|T#U9&fI(puDY<4KYv5zK^0vk=SWYeCrtAptxlwmycka z@>|Zcuse^`O__P>{HV7PgO3J{`fF;*Zo#4J3Nd%r;&g2Iq^<(icE@3ybP>%BubZAb7R^kXm4K#r!c@|3C! z5^Eya`Cm=+0?)Hl*)=Ukd5iKTL2QD;|Bte_4vM1-!##0#4^9Z~?!g^`4(=8pxVr`j z5P}mVxX<7gT!I95cXxNsZN9s=YPYs_>)tBxC~WS&8&ovJ5{Z$E`jEQjzggDH=~;a+&^CVo+Ft z77Z&taFb`Ez{x1^_phz>if;x#-L_6GvwWwib;koeVcnL#!L>k=cWMsOMdk zc*^oqrK15~L6Ho15#W|B1G5kgh{AoL)3lDGF@kDu;wc8G*EMVchD{l=?_>EGt*2n> z*%iu0`Qur$|62?`z7f&jWa}ReOL&4<0-wIAumU|f75E1CC{@l$dl2(;R|of7r-wpQ z3MVYrX=3_H;jDm0&y`;CpJ;$GM26?R-X$w z3wONyt=;42SQe~MM~GfFDFWE+zxGwo)p8R@3f2qe_q?BdUml{ZYo%GM&<`<1v7DJ~ zg&!&OJo4cOi~JeCC;EmB&$v$q6+@v*$Xr0c%~W9$y9UCSK?f-Vw86dqCDIi6YLVNf zsrPAy_CnA1o$b|02Fo9fjp?8NPzm%MV_E!vPOENqr1Fk!(xZ}ksG!)X$Lk`XcHj-^ z)>{qkv1$bIT4_JKr<}9aNaJ7N7HBP4_ZZW_^sEQw`f-QLXzO!>!Q)_ZsHl7#q1pNY zW)h(n8?|^d(B$HZ29;hwd1-cJq^}nE5ivdG>#C2&jfy0$HQ&sc1+lK5mW}n_Imc&n zS;+mkc1Mcrfx6e`3n&b8E&Y@s^_a)#teWoyEmoNurpL^Dpg@S1HC7w;w?! zdc0HCK-9x&k%%IfZSml74$RCq3HbM;qd~3ng`mbVH`q)_7mQmnZApW}3QfTqm3e!? ztn~j>ka=XZe9yIf*Fr+DVBi)X&BCZE&#h{q!Fs=fJp=BL^YM`~g|Fztn7ovdF4mA* zC34AOp8;=H{wK?PMpm*601c*?5t$JZct0n@oQD$01Bh~l0&8LSTz|eN8MN(ibI)$!gB0E2R_9aRM_<#_1hq_& zZ-)Suy4(uWjq$FUu0Vdbh?ZMcZ|l88uZF(`2o+D7hv%)c?fyHin#(5nP9{?g51lbn z8{@+J=0ysYNsdu2W>@p+;!O{E3ZtI?R2T&YUo$(lJg+aNI<8>`1ojfqi+8p@(*osR z-@>z&C?-*v^}iqe9oip@%(992GWF{fJsbh8r!8k|6cgNA>sU= zLeA7<+=9{lM;qzIy{4W|)k1t>nb-|ws|Mg(QR-h!i|*n1)u^4!B3KYq(3*?FadD@| zbEGZuNSS@TW7@5Iu<^hKPvRWOAZi?7Ulc8e0NZ8Pvtj>@_|43Zpq=vL(8M{*Xl3$x`P=z~hTO*%rNiH2BxU}tv5X&7o# zjUGGj3mgDirL!-C~rO{k(0j%6I+Rr0OE_F-(#6?a0Wnp|kP?E(pP?F(7xADjm=_#gEm76`8YMg%jL9~1T>EI>4W z;=W^euFsBoqwYH}*h=x`qUAgQbwoDfcG43aKXj}GKtN;i+pHG_LG*fD5?Ie}hrpu} zp`E@ZzLW6UnGkIWU<-=?!DI`KSEE8Z6N|cUCC0PU1fBQ=AWElke=Sxi5k18Uw&!P< zc4~B|Eg`D`{dzPxqno!OW+=24)Wz%5S;V%4Xe_V}F{OEOkI$=Mewo%#;mA@M{3@Zs zp>gYa3b-8y^@^S{fQ#f9TAx}Gp8juNUl67VUQl8^o)(fBjQxZMgAVpYcTE$3m`G;Q z=0u2t&w%1=+&+2u->K>AvsX1|AZd;=(QV2`o^EmtRo5t_%*_++7?xFELr zNFNato}9>AfW6=$y^|}DN7K1!8bNjoFqxMD=RQyldWj#3r6wLX?=eE7=UDauA7UZIunZ7IwO2ZIb57uQgW&zHV@pXjD^=L@bkC&Od zl7k`S?pP`qntLxmjD{k{gP_MaLk>ONN%&43dRY=f;HxAWlzeb2U`3awiR~LCGN2&| zX%z$gP7R28v}F7dguX1j@|Sxoyz-%ccIVYm@inx=ai-r9+wOMN%&Cq2fqG#1!{+8J5XKu zC-VWqwB)7*TTUeBM|%XZ%TxCz%ZO(rXkvhe{8pOy|B(q$73Om7B*cfO+@KSO70e@zNJV z(#7_|2-j#AWC;Z5UT%pC?J{%k$Y~428{;`rfotR#?+289+k#kbC9mg=rCq6#{FIfD z>VS$k@1nkTxgLCvqJG44jfOKk#|Pf#SgGo;KS28crScJvk`rn$2nZ=d^=Lvk?f|&_ z+_R=x&@Lk45P?kmhx_JF@Lz*>os8Cr93c8d>C`5il~ni}dzaNf2;1}3*j~!|@1aU% z+J~lK%`x;ZlzPZEa?yGV(6^H{ak&`BLs3vg;+}A(zAqBsFV0uq3bXh5Jm2@J=ltv8_WhJk6Jhzv8UZ9hIJH4}>D>6k7+%dM z4NGt>q%ggzg*>@cDpabe4ApWn9j!SAa>Y(+)@*i3xYEc?61_z1mw;Y#j%dLnH_zw8 zIhWO^m(&~0PQ{`|y?3lcW0T*LD6(HJHJk~nMD@tm7k{q>2njVI$e_$pc&$T^|1xFm zG33aVE>2ex2R~;CXLC?Fo70m?w~q=;K4$(i)@8yGL+4E|&XT8%%U+&QB&-^%9r`2A zRlIL28m9*npJO%9)H4H@hyPJKjXrFgZY3p)tQe5&E>XJkLJQ%AFb2@wz-J-3TNq+`UoQr0F6RA^|aJ>;QLSVvkiusVr)O= z<-nv_FRVulej@*80Q*%fF6JomA*ojDct_Aym9SYrWgfY6b=j` zCK)It6k)}CocmV(HKKv=P5TwMP9Ub}-^lrqxc?JS7}W^i{%PQX+(8$RKIsFTz+yOU zgB0t@{{)O)1AQG~=yY{6|8;nlf>*5&5Qsda8pJ(R@vx*l@WipCKd?4RanP#aBof6e zyryqwH~!7(gI87!{?seT1coV5QnzRTphes>!))YJP+JnGml&DX*4h z4?AKqJUMM$=1x2F!J993uH?9JWR+S-szpqaM?@5iZ4|=&S0QmIwg5)H_Y)gptgAF!5X{O@zzC>T*s+eO?cbcR%IUS@v(ge^drH#GqQSFlY>Z(v z#cK8a5M9`5MW!MLEU2DjVJ>*gqvX8F9qgpu*yKUa@l28f#P35Iy{r-uP?VShub_Kh z0Xa_Ar3yFnW3*+p(FjLWPvdiVKRlBQ;YeyH0*j5+@01j=M3WKJXtaMW=d(WG`*vr{ zqAz{k7O4WO;0MECev>jO+#u|^x_whIf6#u$cGIX>OG*liB2NMZ0_|LR`Rx+J~a}5sXNa7YWXR}xT6XS z;k7Uh89wXQdF2Ua zsyDHej_NLWTQ2Ra92Gj4UvK#vbx^24^haS#(QY|M?pUTgGkk5ek62kM-!aHZ;T9=; zMpUUAC@Il(3rS@T{@`M&Vg_TgX2LxVPH6o7fhYQN!AgxeAt?~dL8!I9GKt3RVxd7> zaeK)DE?Us8OW4KA3!y(GbM=p+5T6-h;ZL@{-Pvy6)c>hJhN|zs{mD*FN=X-wA45C& z4vd?5odx621=*Z4A}ot$lh|va@t$~EWTd0UkH`vUb6jiD5$?>0i0V5TaQu$x|gqg!0LUiP5fEwDdZo9X(rqIB`8p2y0R(k<~BV%AN@NZt3ZbkmPIUEBR?S75xhT*4k-Y!{8{Tw`r zyz}UWbYh&!l#_%Zk5b^mCjb*Ke5OC*yKbZ(C&-~0^AX~rAtde}^gQnsqKOG{}l zhAVC+k^it29Jav}6^Y1oT=M#%Pgyt@;2Kl2|u_PbOgIm^u82$t8i z>d%iYD5>TUBpILzk|rOLCp>(hL}mxik~1!vny;D(`tSB~Cl6^Q{}|VbIbF!;kv}%T zXg7;j?_j#j$&x2On%kk&6zDsou7a2gPJKIC_kE3+Eqwb3j3&hrcG4F`>?@A>C`IH; zmybkl40*Y$%qn`iTv1~!GrwHtxKOuPq7)ptDl>FzhdHNgZ|jtP#$k_$`6>_$_k5BM zqa8xf!X<%S*SMzXT@SH@^}mYv`Fxr6bCQL3)pf6xbn%KwLy%m9mcKB0uT-b7-wP%t1Sf!JsET93TMCpXAPXX%~AkfK!%FRQu`z0@%GpYcEj-& z0K3@BAEw2K>#XAs2qNNmD2{J!!5$@TiPH8wF$7SX!Dz^7*I&61@u^Om9EH?#Ohp|4952+L_#fvw@9mFrso3T{R+ncCD7JQP&QMLnE}m zP#mIyk=ul{!FwZ^W4OjTpZx2Lbj9-|ItGsB^$^rfY_Y^FnVj;RbAa^qnNGMg6Ds}q ztM-CGjA&ybm9Lad4?Lp$0u-_cNj~3Z3{*9LW#c&$DyIy0fDxJbnanf%NWr9WSBNr) zVsbZXn?%kY$%9hz=$ffVVvmMdVV;<+1Cs`-{<+(lxk`qv>xk1N81t`)nh`UPvx;Mb zUCH7Km?%fIW+1}+C#N~l?o}_`y^4}BrsD!35^<8?*Yhhz_+Vx8^0DiVT%)s=r28y7 z>iHu)rZX!N$J?k*{@%#bOHtjEqU4LluAO9~r>d6rO439eZ38tBzf746-m)B?kbQ!D zRrL+O$}-ik(IR&KmvGn@4JKhLwHyEbm~WM^$S)>ny=mD7%K}&BY>NttE+M_)qDf1F zJE1gJaqM85ETosq+|Pk52ao?|g3X5@GEd&gnX2Zb*w5?4t8(f^DN9-f+x(Dd6L!>= ziMIDL0>zS&)q!Gt$R)K4_ceWNSFY`&6OyyvQ8iHH7Nz6-4U`JuVBR%3f>Z2mDZpmK zpoLSg51!>Di6X%(Zw@b3r`~QjUE_hRD^$I_Lluc7kB<3V_f#}*tI1X}IMi*-;?=C8 zQ8pZp=Mz$V{{;0;M9_25*_Ra+L#Rt*C#O?mvse>uqXW{1J*{D7Jjv9lIg-q9X6maD zTQUt7Z&TgH+ips~)M+0{L<+c%gpms*Oe)(SZ7+m;oF5sf*%VRM=1jU~-Q{}IK-6e# zW_R6R=P(MI8KAVXD3%IR1~M8XgQ}M&v2m~!msrN}x~oe+i!pZKJ5L;ZnSt(Kc1t{% z1d+Kvzy-p52V>!OT5_p_@G`o+y$KP+9>C_Mf##~Uh^P&pBpGFvxMN1>Po4cXDs*93d{tN9;EaY^3LvnvQK z`_%HcDh3ih)?D07?k~6OyL<&AF(1*dKB>kL%F}bbQJ<~< zeNfq7pAjYHVJIZ7aeGJihg$TvB<_ZHXBm~BAE)9WeymZ{p16vY_hx^nKb$O}) zEW-TRVrrrAzVKC=;>cfgLR`;)yD3+c!4l&TYerQ3qKv<@kkO!`7CV;isZGSKuF;}{ zxpD!|<-Ts68jmfXnxOy=Lwl)&@0N?!I$7&wR*O9wO+nGPeAZui+2?{EvR`w(BQca( zzuc{O(jlD>8NVj{gi@78m`}~jDaFCtL>Z@#jaK?b&;uv`?$5CAL4;cmw(R=lm3HI( zW^|W<(R;1v4`Q%8GyZBJ|AN54L=F*TdaimqG39xQAzug)G`VQ3aeluY_T|NYWeq9Okm%_=g(7v@WWLMH~#z*0^rG+je( zy`qS;?IvOd`99jk&{B||`i)c=i6~*qDx+GjCKz?inEv#DclhO;e`e)K8^l-LmDj82 z{QQ~!>cPKPzfD+7fGPQ0QdC@h*(0*LF+7O6(l(FKVit2FDC&=szac>-xC^DShC_C4 zn}034_b9Ae>4!;|mgDioj%S{_klWhkZ{a)_7OD4_N{6&d+Ja+0g^nErgN9a$0SZ`| z^TbSzF-6nf3dDKaU4+bvFy<*&N;s^%eG;!Suum-e?9xUs^YM9K)p!e&6gF%-U#Ym& zuth!M+2tY88C2Z(u+Fev0V)3hO{yJ;x@O*5~C-(?kIX^Obi9>?YCr^Dn%9Q_# z9x&DDiSMXEO6rO6Ex_`k)zj}QHMhtOUf^!j2?bx2J&C}My186*4SsD6R$P=Es3zki5eU$W(B9p6voXNY-JJHU)M{qXJT+pDrdM? z+#bT+AJq;L!clSTeDoDO!m2WfS)OdVH>JMpeYcjKvBkQ!!!oo-pYRyJO(HkaIVmOZ zkE{1FC?C%r(^TiGo4&?irwqb*?GhfnOp#XSH!mcZ7#1Chp@mD?g{>Hj$umeKm;Z@x zr@lR1HlIrS_M8D9QPq3q;MPL%(2_znJR8kT%cItPyHhz_aw|o$&34M|dhvyit%2P7 zCf$-lSzUcm8C^U2XG7^nzRz05ysg|Lsj&N_y7n0)Ct6cX{l&+vN6EDx9*UzJ5%5y$ zl1Ylbd%%alXEZR+5avEwl?E^`>IvlPmWR<+Fq1pri)1XKO-=4$W(#e#$vS-eN29Ue z)>k-}p;*}>dX$EYnb{)#x`656JtX0}yU@*s#zQRu3EQpYHs6FrYf#Vl_ec4$Ra>!>}#9o+5+!Po;WFKfz{Y2+|w(lXP34}*TsB|fW%X*T4(HV2AUySS*~yk~sA4ig#7{#G3?d+MLuFJ|U6uv8WE+ilIH zUwS~u28~ocMaP%E%iIqDKh6;DlsiU-+E1GHvtMa=W+|@{bm4^+3<4^zzYe%g$Y_;~ z<6-dwSiX>hosK-9ogH0YVrI#=x4gVL=OA z`II6dGdCMc)TepRJAcA-zFo{#Z^%1W^Q*;jKDk6YB)tqu$e}bldmOKA?`D*)L}d`Y zc>zzMYI17=<{dZPdU3$}R=1)6cK@n@z_wpQV>E?v;$arl2&xgAVJ1^2LLH~3erA(d zTK?=nHo~?d;$wp3-D=arwj$x{96V~ace^gnRSMdQ2+@l}@WQn_;&w)xZJ!;NZ?rw< zAn3@!4*#VPA_Bm{Jy@fU5cgB;R#~;tk35xib%kiIw^>1~Ks+3=osZz_(K527l4{IV zu-=5uAG?{d>avH)$wbUG>w}MuM+?KxV>2VNm#^NK9jR+q>VYZ8?Jtnn6AnTHck_JD z+QDJn5qQaP8x*Lin-qH$}2p;92T%0J+S;~YTL^*jxZ7|A~C$6em@ThUkg4jIo z%Cvllqm4M7dBE4K_J!qHhc$U#k9P}`TE@`{8ZN3MJy7WjoKyPVxg4sFJ!*wx+n~qz zDjlxoQgwa&g;S^sXwYf;>s|x8*g4M}Wr2?-i}oFpEkzu+PS7-ug>&z=ZriLRBuOtn zjZogc>hJCCZxEP^K8v`(4W(dsA7wtH0l}CUJX{C0NWV9B)?# z=*giU6!8Sa8mL_vXJwsm@F~rr@Y>sDh7yI#Oqqc{PTQ##WNYb!RM3Li>%lf?iwC7j z)uRzU2m7Lp0Q1Uv)-FZVGQoN{N3-8XrbV>rnfEJLP&1-bE18(mU75O+fhV8w_azDe zbJaADseJ9mKn+2GV8fyB15crDTKs$X{1bu2C=yRv04yv?kmMull3KCsP&3s~fJ^wNC zuvS<+hu-cckA%c_FmWUo*SwnM(9gpC+8^l~u zxNUuV^q+Yy2y^{%2Qg)~i$dlonE78d!fUC&#grR-*M(e*<+_1qvi3ip?=i7xd%)GOMSsviJQ|+e=ahwyhT@TDnkT=p1Ds*j z6h?A4IIZ_!A9P=Z;9dvVLD_ zTvgu?h<_llP6}$crgi}xP(tnK{4tBcvzQD<7(jC3VV9xMAe0Kl{4Qn=1 zupK-VRi|L&GwL1DdROeY@j-p;edsfs0k@VGIacBzFev)@~y`#|ltB?xT^`c$O#}Al}njnsn&jx2W$uqS~7;qm^Kw%kn z-R3df3gDsJTKaf98fOsGmNPM zO4&Lhi%Z^7t7UudzPnIp+S|S?w(10)bFSkzN=5Wd>v`7CROv<{~ofleGW?zNu8iNLK0dpv;ol`@HG6u2dGV7 zuM4{W{UL030@{@AfS%7WP?M#(!UN(66crhkAl zhv~5h8+?W*E( z5Qjhz<(OFT1M_BW6c@b<;~|R{qzd-)C_q``s)n`%R63W3h2vdJIwqxG7MXoGfiTKx z$w2QyYm7TPf%L`0`?Hj48D323$x@Kich#7aUz$SX^|q6y0W=wo8L%Z$qAtXsjN13& zGd1fO^TI^s|CZ4Xrwpr*9K%{9&=LM$2-S@Z}k$q$f=!3eQE;k9%M?5V7C&`=9 zpm94vF-W`X9n{@Ffu~-!fD6D@@PtISm1dbw(#u7L{}_J=17X-@^ug`v)`z_H8$_fUtsh zDbxq(?qAMm8>5?Kdhe!5>;b9qr(vgTwcWQ3psR{W z0mtpRWY1@ro$CBH3u*_&73*VCJwfPDo;0)kk34e*-NkQRc>oB+?r)2XjK{ZLkwYY*W7q{# zP$6Kxk(QhO&Y=OeG*c5)U!}>-7Noa)I}fj_QM~Y*{qXT;AM2}a+iRX7I=)Zo2|tR-cfA!Ux+UGk=@tCoA)%TMn;VYi3IE<4;c|9lV7Ykezu&U=A_vej9szvujE4 z=}@8l&;~NL8vz>w_Wtwpp6FO5z}7fDUZ{QR`B&k_MU%Y(TRUzSzu>FKJz?IznW+%V zO-h6CxHU>xp3OoHGohXGy2Xl-?%%>bm{Or;;A@aOT#zzJGDOZhVZS2DNkVVF@z529 z32TP2-!dxKUQRvXi~#BIzeIspN}e)}l}``fTd~WwIUK)!0g@Rgv}_eWZ_=3`72&w4 zb zg+GlRgE9S}I+I<*>a+!+8>p-v>nr`0)3PaE_GO%%={0vw^c|XZAUy)EaPFyy}55wUy#zU>zCm^2HRse!ksXxrC$F zyB;Pos$pgbe`1_SD5-?J(DkZggJiWPR4p3@L^IX54#yJ+um^*=4|Q8jy8Sjbd{6Ex zR)W_DzAB3#gYW=A%sMP13jd?k3=EHnroejusj3)|%vOou*-G|-rh1e-;Av^?jUA*O z#ArrIewe{mi)i2#uo=#zaTZK+z3uJ&Vw)BCu=DdRX2faijfXYJc|pYX3V0CVDEpT@ z=S>kgZ-o2o14rM<($RNOQ5GQKP!=P>LRmUHVHEo%onkfHV`pPyZ56dVq&0>1C0fqBgY1@wvv&sz_wOt@j;p_S6vD`Y+{Udwc z@Sh)64jebFt0Sg+`ZOkPalga6gVpM1!F*37y|*M|{C1Thm&+>y;hrqQWzMB1AnDqS3O6uGUkfCH^ZMHoM@rcj!m|eCw38AVNW##-GdXz!{4X3) zkX812Sr5YGi~?oYRtG?5!a@-%w^Vr4IIzdZ$EWU#%XhJ^G5zYlP#i)+q`COT1vU!- zc;;_r?polBJgIiXFY+jTKXk@GJmECGrZ3=~JviapX2s4a*@SyYGG(tt9lMwd&7jvmdVS|AK}FKsVyo;^R>V_=sdjyX29p$M)vbS_A%fFp5y{JV8$>L zt(2P8hGB$B9*F7-u+{L-7l3#65I}_y^!qGpLqRug_d&fE1vF&OjAoEaEpFKD_IvC1 z#f)WU*;0DQgksfAOkNZe@0EIHBX}fO0;`}(AtU`f@ph4RnWfZ;9AAsoxqYK$#4%qL z90Rjv6O$ySilSpZ6hF8|6zfiB1#d2>LCo?Chch?B$X|QQ=_`v5RJ(_d9sU)j34q$UlH7e1p~pD%A#H*-!!AU>Tu+@t{8r`u@+~`P zJUgV9G~_Po{E~p2I`MsnTi?6S20&(N=jq!SAn9e=vR~1Dm3fBL0{`Pd^ORp72j%>y-1afG%Q^R)j>;qlmUA# z%!ejwtoMGIy@3f>c+HrVl@F)U*bw+MbUz%Xi~snS`!`W=`92MGJS&z^JVmf?z79$5X=9=PCd-6^*QR(J zk66#p6ztN8B##^aE5DZ`Cg2D?F^@^Ik0tz;G0>%v%COg&XzUSA8s!Bqp_eIq_I`4Z z>s*;zUAS97G7euDUTFcJ197GyYV1-NAG)&+;fS#@_nu95gFNRDYGR|RIRsuV)8~uy zb&5n(<#CfVt@f)$hMZ*gJ|29h#fTvO3+xQBZeiKP3Ih$d4s>BY^XSx{kuz8|@srgo zl$a8IWmH7cx&$q%@*5eZsFpsBTC?!Mv45TAGA?ju8KQw7Hxz@=cwPaEyr_Z%<~(*| z5*za;AHe4gImDxsRI(MU&#Ka%)}*XV*k%0pnX8{+{yIL^PwIdfPG`HO|M+Z2sWpKm z(k>4UYW*8kC*MRh%$tMdpR8N5YA6OY-fOS%GyH`5tyoVGRPXPO7yAOub?%JV(DAapmL`{VtT%T z_T>G`GO{f0qs$!Q!0L4(e?<92`dHkuLxa-d+RUrX{%2I>CGlxqBbRR*xw(4jl(Nc+ zD3Tf(?j)1S)Nn{Ez4v~5A{6y_)UYzaB=5mhnkZ?jS6O!@S}0%fi(ys#qlLEw6}tq* zxwE$0z&wLXJdF+K(84?3riGj3jq{qBc}@}#6=l5Z^S2Zno~P~7AVu=HtdLH|bA`dI zDkzdp(*-I^%}$!X336gD8bCb9>-R*wL>e(@On5|ZA+~sqPy+}}jxFN!FZfm&@v=@B zMwrp;ezsOGDc69We|W_ExTPD4PS2s`#c_I8rqsgA4ArSwh1+o`8Obi@Id&KfweV^^ zgrzJrv6_uO8cRFV81f9wu0$lxEh9g+^P`pO_!?R9ANd;cL2YJWg1`25xg5|` z_zpi#No^HS7)2ywaCekc^_;}0rOUupvk-F zM*wrs&Gl_BSQ9Q+45uaJA56S;7X3E~A~Cb5IHp0mAJXcm)p%#`pA|@w-t4uzq*zxP zDq-Wv%h>Y~1$bqeGOO9b5uvvMyIk3(zfG!DK*9Y5xn9W{$+l6k4Aq3#XuMWjo4sNW zdmrxv9H^R+eu?H9aU%q=RU00v`cps+SkZmU`|be~B1buYUG?p&%h0={v@qpQ<}Pt4 ziNsG((ue734fhP+NAmH?8NbNc_>iD{iyDQv?HzsM*Q@h1hnsy5uAmBX?jdBt)3%R87rQ?GJ82Kn?rH!ynkqy9CX zJ_ZwfGN4Wpl2b&*5NG;Bk7T>Zd=_509e!!S!7TZqxNFW?NSwzqG;jt3|SBxsS4I(1gj92 zSG9w5LimDbhZMEy*8h+dcGP5V9VfV8S`4keSHZ5E4ls|}7V6Bnf6Ssd%)Y}F7kkeT zHBD#CPRFLdUz8o9mz|(qqDBmw5Ce@caY9Di_`Mg}%{wFzTMPZY$>>py3e|3?%fH6j z5_e|#Z;4}oS)^m6eQ82x{P0AO9l)Bwp7K#SBW}#_d|n_kkV-aH>*hLBn;|?ZFN=MB zt>)a%F>78;ph}D*bR4}XQlMDn&}2DbDAOK4F5j!Z{9#a*MN9wCF`n@Hhn`JK%=+NN zL8?vj#CH(dr&mrB#&evk6h*FH(w#qw58IISU~{%7!oPSiJHqvo!ig9t(Zdmexl98T&W=4O}qUMtm^w@bTOl3mmp~L|iauYbPArBXY zunZ3b+W3U)*Nk& zu!+p>F$Kv|%Ido?N%Pk8b*0h5>^mhWA;ZD9*fN(}hgKpcR%QQY;?KFSbfnoiYWbS` z+OF=fS&W2$R3Ulg!O%?G=m4=najY^qirzZA&eOuMjmWfMG59xa1u3I*kk4O~Tf%{= z(cy+$mtC9@{Y`OC=R3+%I|dKO4ET%@kP29_(7O)7XuK!a=;{o@3`O8%*wc?jB+Xa7maB9X9gL+A}kh5$Mx!hxSj!51yMa|Hca#=dVAPwo4c=X^2;s3W;?$ z?NyU8?#w0IfW75SYcE&t#$pa08wb}z%VR#UoKWx?nSm)5{IeO9X_>t;7?iR>mO;0^0WU0VFDipyCR6X!XE3^Bd(I!?ZcZeUVEtSQ z{r#Mj>H|~DxvP^~hUw+CEOjZ z%#35Yfpj`pld|uMiGy7_1q}*Krm)mwqMhUg^HZcZt&iv+mquW6rnSwqgMA&-DrC|? zmFL3!OITExEQE~FIIv$GCqiFgZgQILTKn}5>*x-5(j)`t#0<9UONg?Q2#r@9a~Wwl z#%n;84QlE2-E+R^BekGe4yz{2Trm)Mj;iJ$2?{V8q{9zYnBfkoMj)B`n){KF>{P64 zmQc>pEn)EYPUZt~#?8px9eA=v|1iG<1?FpmyrJP(ji17CfJiF{QU8qcCS&cns8z4D z<>uIjM3F2w+5DCG+znrOxQ1)g-%AOR3qU>(o}m{ABQd335wfEoz`>i@^a zc^~vrOA#x26rdlVQ`M;+3hcxzW(({DJYS-}Z3CXN{@)w_ueZ0WiBtIN?k)@3v#Hm| zU=e?Np&e(Of?}X@+16fXCzKaT)#SFQLHgUXUP8KR2bYa+7(#th+zYTJ> zyf7eulR0@o!^h+g-1vVlg;NYmu|523Y)m1kE<0TN-{?&Y#lYjZp98I}t^2;ei-I!Q zn1p-#$6OpE1%+IuXy7YgswojD1=@!H>wpEe``5n&T!DqRI2_cumW$T^+-2T^5+91@ ztAYcHaPJPLAs~JQhJ6`F{Pt=8*JJ^=*|)*{|7?U-FMl9l6#x0(Zo!5BP4WNEUjNOe zj%SKO$l*>2L_D5YRR}n4CEk!RYeB_RG0}gcxWN3sePRF4FXX@+!Y2Ys2Y**4xn`6T*bUmST|F`mOtJmHbY5V92)$;hJOc zH$*zHdUG%ZKhE!Dg(==%TZuHbww3DMa`o$PIkSq^yS^ecb@$_%ISTl}w~5i_H!s&@ z)J?(n{t_d>sCf+(fi}_b+;p(jVHJVXYn};SW=Wos-z?#SFgZE-t~R+WqzF2dGX*8? ziLzo;zC;hs@a<$YQj0@zVh9*CM=e^}&zUS0O70&kV--z9yc7Lz?p&dj=5ybtu}jyQ zxmfSSJzhQ)GD6ST*8BMS>W8g>YG*z`nX1IL#Sj$9Fp2i;*Xl`=!TvSgP%W~C^`Esp zo4QUb!A|q(^6%H=(h#S`PSdhGj4w|QI-FBdbJyqHEJ-6wKIcK@wJ&QW)g_}w!b18p zXwOY-Q;1SjRl;P$IRNY4X~8|^qr0~jNuR>Sw-d|0sCMe`&pBaa&}=4l)ypLUt4v_G znO914d0e>nCQfknp@Ql~6dNm0gP`VjrKSS5qg`H)k>Fo57Hb*5;A1Y{G_9W7)xNf1 zV`{TW;7V7fmOD`;RZ-i*IH_vB<+i+F^dZu}-|4MDUF}6L#*(31SE9yp8m0r}0~WWP z>HSY&$V)Mrdd5i63sEl$AI-nvA!kxr&loqBO}UMDgS`zf6=hahB&T-w(3G=7hgI5z zXtdH&^GJFTQXKGmrPIF2$tYR$=gaIA3rY$m{~r`vjYQUq>B?n!p>;?|G4+0x=-?2Z zbBd=Tnw0ZQeW$uW1MGO7U%nHeC+D-96ngiEQN(QN(P-9)(>5(*D`fgQ?nrMq1A=Pm zV&vs%tI6ZaTN*{}{AKkS;expkWs2J4TB%RUf03s+O=mh|mi6T8EIMc9eMcZy8dCX~ zd;n_!efHyO|35WVXR_wSjU@5I@p096DB5!L%7Y7R{#E_Ot6HzD8vXSf8KzMNtV%qQ zhzJOePfvE~U?(hFPSg}tUs(xMLaP1~@6AJNQQ^b|USn1eKJ)ywluqrh#*zZE;HLZ% z8L4{6r3Vm{$f1Vj#Hi|iokjQ4=N&G{o1LG3{>0yGkkWmj#&WjfN8;rkLsTB*7|&@} zeq(5uD50^Zc!Dsj5@8MV$-gT;l4ic1N;3?;>@NlK=N0!4K8GfJ>aUD((DMB&S zua(Rd4D0VdeMer9n@%i++$g3^ApLW3?*R>AyjtgY3CJ>2*HG3oRR%Ir;fLF`n9$e= zq}CkzS8tka%U%x1iZFm?bsUGU=*dG%9t}iWS9IDcSOV$&tKa|Ye@STRtBoh6deU=H z+AqMjdz_ezEJ>54X|cUz{g52+vN*3tmvqo83Sl75fkmcw8`W^(j};K6%vwkhE4%!t z5lDp>kh6Ukv)(x#u01m0jJ0%v%Y26<}U;V+ifj4^|-)grQkU zsQrw3Ot$+Aa0v@wz@R;_&BN?ArYLgio(t3R0ha`m2xf&EWObb`XFz&`)6lsWpU}u_ z1GqoARl+)X-vC@fQ|;$2uOXo06wTLu5d&C4)`2{0Me3!@aeO=f&M6Kf>uAgG=Sd)hP}4|sA=oXrn(iS4-FtvO zGqdy47z4USJak?#N$-iR_54q(_f=2>(CPf=4WQGU0Cvf6rjRyjN+AlY`O^hKS$eXy zC~5VklETQ*nw~teQGr z09>8-c6@|w{VGet{3g$6V{Mnp0#uy;<3aIR^AYQ*A|X(J1bRqU0H*H-C}m^`xE7t# z4emZYjY(y%(cUT+OX+n~y?ZU=IosL z1vA&|nfH00wbs4*NW*`BthAs_>Fxpj!3vNQ*Nx8QITL#c@MDj>0C}so8<2{2kAZ?d zKwlJ`ckepU6U2ufO>g4byK=0W3L>ON(CiBYJk|#vJVFYsms4ASLl%}S{BxP~XE2F# zD^C_55IXI7S-+6yy%LQbq)J~x?ZDn9ytp}T1w9$%Bw#5$K}2xglmFvii_1i5HO&0)OY=#WvT_gri3t0Rns9sl+AiUd4PynhLiasKJ z8p#t6fHvnINzdNku5>PTzR|yn{s2vja}^(X&p|_ku0OusfCTsRQ_4Kc&srsP1uRcQ zV3e>oW2C=lSc8uMS$sV;`C9+wt)EsxP3Le2^=bZUE@h z`9}{1$L3Ec2rWNYL14q)B1oTCN1${yfa@oXIx5K@pMQc~EAKsA&wE6;L3tVxCcTFzx>gNPm6+)V~$h5xfIc z2Kt&XQQMi?^kY-ox~W`-N2|&5+>q6hs$>U;?R}W{>f1w|M+Uw5L$N3Xv#O_CzqO`U zUvZUKmOp>|VIhy5t+c}7a|r0kzGM6bb%czt_PXEhS3e%#+BYCq{!xSANENu@j9#UqRP<ACzlVs&#gl-Qf6} zm;)o-`huS32NbclLY}rAWZ$Enx3+(SprsC!5V0btNC!3F&VQqeMP%{6U8WcqxT|7c z{vkfEFIT`0GFpe#5s=MdO#Y0*b!MWoX;)#u{bZ#ioC!$DZTBA=$lU4+j}e~BO0jdS zCM?6F5*#}FZK_CZNWKL++LT^eDRQI~%uEF;!1H?uC-4aAF)l4|XF^Q1xvw%CQ8%8| z(mob*H3`VPq`#xh6AodResh?`)zadSM_5;rr&c*I2i5AKC6o&x*x+1Y8JW)1&Pz!-6E!H==@6$ z&SE4FDx)J(&}GlDS`DZ$#VK*apozKAslp{&*8B(iE(x0@&l`?1X{iF^kE>I5XLA(Q zOzJ}94#05DQL3F<6da7A+?785=#d@(72!OL>JQ&rXY;;=`Y#}ff)`d0OZcvhaKEgx zGU5)U6v#>26*j=T#OG3t+2lKFeDOBPISrvEwl~^U@VicMX5SDUqt1D|N5BXF*9n>? z^qykqh~4}&$YtC1e(G$jdY5xMbdYoKn~8T#kA#&W(xi<+H+QV8J(=?ck4{DU4Qz>~ zU`#7ovz;+Q=$?5_q%OK2Vt9GB`R~5P;SP8(z(|m%AMD&vQQF%48H9AudF<)W=qq)X zwAOC6kwgtA9wO{gMqS!|9QO|6&Z;0-9aN!a2+Vz7Bno(yov`4j3(sk94}BTb9OWk$ zMzKYOYz=ZnbSaz*K#{rzY!~1=naTuLzP`Mxj6Yv`(}2dEO^BLW2ID6E(DKg4-_dKW zro#Pb`pWCLKX;=)00x)HTmw{LV^@=+1PuigW~eK+EttwCzeI{Oq5AcBYJQEkAE z!$2o@0bt=+0Z73|Z$MQLP=!?Mz8aMzlcv5S-4wSEM|6u5ALU~+r;&IYnUl=&Pd>1- zp9_lyi&a6cLA!D9E+J}%#W~GdOMX)o526)cn0CB@L>jqSA69)me#}GzRN&u>`yLOI zlRl$u))yqEq3@}tTt(=)r}HNg6*-SON2!Jbm+=#Xkw5lI)Pl}e+QfyiTOwO6i|@Yw ziZ&aN^OS-hlcb~fqwr%CqFf|uHSd3Pg=30BdDZ|AdR~zXioo91x_$$T9#~9xRpov( zw~)r+Y8rqI=DeL+2njY(qFslR+&HptI0Wy4`HJ~lKNo3CEW@B_?a3P_?Kd?-rDw>0 zG1@cFLSm&Hi-xtx{Pw%)NI67J-2Jy82O>h>aACv-qacddGm#+qM&3zj01_C0=87?3 za&`c5rto)6-hB!mWIYEQ#23{QVky2;~u<`TScS#N-0Zh!uxfGME*5{2IzIH>Ej5e}2s zUd_T|og&4M6>Ir6%5k@$8KDSb7?Otrmrxlk&l>n7(52x+Asnv{_RKj&u$iO04IJ&` z7Lv}Wl$P+UaWjdDWo`Z_?4O+D;EI(_!xYbxGqlKj@s%e~Dv@c$BRIfxI(qv2SD$)= z?rZIqejFY`R1wpCqd!n|vSpm7Mgmib)GkeBAiB%9Zpn-Ww<)0c9n7q)E(lVDMaCdb z97d<1CJ4Wz&g0tDQ;kfC_C%@)irOkzq7Xocs^9zN1T{m(t%l^b-w=eMDrI{i+s*jX z71WXM=0B*<{0=YU=Cim4*T3aZ6^qF$9NUPsD53X4r-adrlZhPwG; z(@3T;l&^@S!Cisax$lFCN+ob}0aR#BQnhn)E^}3x$RTmoFv5-lX`BNrUjINN|M5!p zC4{#mp;BJAz~{L=O+Gdna!eOI?lZ!?fT zXt~z2&YZvjlRgsP@S}^W_AS`o91|vE%SLu`eStf|%q|~BAg4%Q20%{5F`l^iG7u1R zJMJv9!TV*O`TL}rji@>iT?vtOw72N2n5lV(z3-LXAxmL&FpRzK)7!$F5tE*8v06c< za0?#sgyWl85Y(=Tt9Bis^w#J1GwYmy7_NXZR#wNe<%yw@!-u9Oq;F-9YbnMQQlC8r zmknFSKWB*DZzl{Ldz=v5K5)peccI;G<(Yg!^dqoov<>r;;X++j4W7;8tuH8vEsl;) zF-%MXiZB*~-O}?~Ib)^~(NalkB^N}ieZ`%euqG#G8u+~)Qz*%OgD?8V7Tj1Gr$1Jp zk>Ts~UA2f-lKSx*)6ji*(4g`@waPA7Q}S~B=2Vmka&yzpMlfo{2o7k0c{??6kBW}C zGX9C83@al2=1fYGk$}|dK;$ANIF3}rk+mN4MSCk}ZhuBk-kk{hqQFJO8DtysdulUx z@9qN`P8RqGAjKo5IOny~A9>=vm|RvjzvlvLA6mT?&^iiXT{l$ zlvnyCj%NCb=#>984UCu-8C5^ID3MSbZ;*G2s_Dc*rspUB#5KN)J0an-5CS%M6qoWs zB5mo(MQqJ`pdE|-l_~k5R2Ri*cbM^uBf)xVqq@J$J=`q?c_u|Xf8{6 zcEO2k$2Mao3`Ji$R=QoTq7fn~HEXX3{io52#z-L$Jx?!=)MBIOC8~*EpVtofOBNjS zGeMAO$E5zR4>kV54#z(QUX7^c6tE9f6U_RGraKbV&dSpUbsi1|#z`So%AztzD@C#z4sYOrqS{c#i!x7lC%V@C-YD)-9AhCLR1r*ZvvSwO%g{7sixK4q1Az)*REL20i53NkFPD zPTEfX^R395u?<)?Jn7nH+*8KOa#Pvs%PY#5+z6+t_^ruVSfv@&OeQ6PRz^*A5&BST z;~5VZgtY_t8uGo4?__1fD(MUET=+Z!=2BZpKD<+T7awp&n)40ZXD)g6JPT;!Upx#$ z&q)rs;7RBCD-@`*rcr;l&!bj{+mT|D^c5t{zKrk%mIP1t4k(zam0~r)#zQ|yvyviW zaI2kXC1QU4xKwJJzYN&X;wK-W%r6f~vQOy(NkauPres*bZB+0pW9TFfAgz!ha1zZ1 z%k(&%kd01pku*bC96^X1sJbX6Lc=SRWo_Yz8ZiDY)FV87WVD#L??mqz;DA)@>tBN0 zbj+?0jqzReYd4-1!!j>~L85C)7>I?IpQTAAnowL(m`_#qLJgQ9j-hvKHwuChHH@6n z%mV~>7JG>eMo3hFE1oN9AtJ%qMV;sKx#6SNWhY>af)Q7Q+vcW~98Fl@a786&#KyCl zE`R1Ig2A;n^>#yYH$@f9G{(i4KGs`NCYfN_qKS>iP3EaUcdpRlAd@&8+A;qZ!gpcA z^Pi8?A!#<7;3wX)!`Y6r4RAJuS!0?Ptf1;qS3V1SQ6F@6(KT)DsDi0+tRj)ahOTb< z{Y~98=kDhXZ(#f4_wOdB#O)0A{Sx*4DCgf1aJwiGjqo%6uKVo%bY80H@-ITv9#WV1 zHZ2!*H`N2QV)b6FWOtC?EMNlM|$x_&x%R*9DD z@K5DdO8ZTn_?xhV#cf7(EiBv5kEXjn8GkxmNGmJOi8cmW4Y`@fQF(Q3T3EM?zAI%j zSc?QJGme4$t;;v@Nv0RY_>vbA($KoEKeSM4DfKN@J?{)YoBH}jz~f>J=48&p`RFf& zMYbm;{*1p}$C-O8rKp)nZuccpaI2~iZVhaLZ^=aUCet@HYg3KoZJ)qseO>#W>%39RAeH}Ox zK|DtKLt*-&b)eAP*LM1kg|{QJ1?|MK3)ps{4Y`Tc7(C(zNIbicQU9t#TB@JUXP zZ7qVx^^;7-J8@J+iup`U^Tzp)VL66)&rZ2Gmor^*w!16If7Z>ZvH&otJ# z$Na#7D&P7({&<714E`OVv-7g~?uVS<2(A9vzYW03fiuvv%<07Te`8W*Pbxr^T_MJT z49LVe@AsT#j;9tDGPotDw9k!;NJW4hUzln`K5J6aDB_TX|4b8~*)phgI_e*YC`0+f0f>PMBM&SinB_tqPT zjtky@t$?%a3{fuu9kb}+TP*@9+Xal0ZA+%O(Q$K*$VD-}I^5~%T18_KBB1hd{wuO1 zmx8&X@cI62zE3P{O4+EUXdLAqpdW)$Q&k9b;d!rIc z7pN9QohZ1n-b^sV01g{WT)Ka*Vz8B*C4As|Pu(Jlxpe7m438b0|I;3f*^Ka$mkLSF z5`&SJSg~4IU-aRc!7HQ3xFxaw>lGEyRWbpKBi4~R`GSrqZ1pEl)qAn`=^`g?a;0_! zHzSc@-f`ldtHHMly7-gMCZRtQNXkpJU%%;&y;7@Q{MFR6UVc^NKc4l=J;w51> zdc&Ej=4x$P5F-E?d%h^^vF!c=R#QK0-y)s1i88CVAc4gH31$GNKTXJ@zUGUp52USh|Z>!SX^ zR=UZC->no?wxq?du=cY2USA~QX=u2~;w@8y$XB49#kS6JE=>JpR$gc*^pM5;6GN2k zv{?-X)?E^or0Yqp8KXUqhu)z#+CCv=x7B-u15%nY{`)h_60aM}!lU1ccc;jApzHF0 zmXZz9PuRK%wXwg4-K&3MR8}XI`gALD@VQ&en+rEo2V^HJt^}wCHvh@-y_~WjI;mvd~SNoYTb z;rac1q`(O9P==6j&pY1n-!FGd?079^)%DSkesC8hI%?!7q*zpCTh+T<<=elHv{b)N znX$?9v?$HB5)wcN#CM`Kix#O%PcQ=G^2jn2^W_daj-GZ>s6WKvH-oJNGTNI$dkh>6 z>qJ?H6bDNHq2*Z=RPRp8!2+(OX>XQc?C|(8^U3X(Tfzz4-7kM@HzdC5!W#?JPSNVv z+5oXvQyYZx_tNS-8|&gG$W>YQb~5par>{Q$jBpWaIKtXrRA z73CSboqRWQOWboZ%vyjFHz}=_4p)c zI<-?(A)M#{>E--b%*ayJVhFKYZJ;ENE{M(V7(T(+mgop!TH6b(udW=aknfxEn@2!>9j?M~s#H zPO{p5pxVen{#W}N0-mJnCX~@9P~Yy^&b!Qoro{If(p-L_=Jd)d4#(I-Tzh+KTE zerV!9+Miy^qeV9wL6U5ubUK_fy_IQN64kSo^|;^`f5tv6lJW|{iVcz;FfY>2B$%ib z`HJr&{_lCe2JsR8i}$s}Ijc-}^`s9mw^E-eN2MKgxYrUeE274(5fF8EFO`S?Vg>~Z zb&rZz7z0F~RW4)BAecLy)M)qDJ4olV@hb2{Um~Ypu|sks<=!W?;*;38$=8MywVf`< z;7GZ)_GTa*&LI3^BwsUNzH#(MbF9mHijam+pMpn}SNmKSt0DxdI^^VTLd!33w*3!- zYh)0bf5$D}*LLpvlN8ndY0OPaL9AW-;c>k7Ubm`^WBW~Q3w`D8uzqTvIVbLSET*cI zc}+toK8A+x^DnC9U;;NET|`0mHBW|4wHGDzu(#D9*OD?kFg9pU^MpJzYi}b)_pGWJ zwLAhkX4DZ95gBO-h&hCR3)&KP?zm|zmkN@-!J^+E3`?O`^B3svFnC|lQ1xL9Ta;@t z+qLI4yjf%ZZS`@`DX_Bw&R~{*AoqonUGCjpJsrrSL3D zgLEhMN!H*cG2YEu)&Bw`_1W_?CK^YV_OG+gseys~EL9nWmwK-5CIciS)2lg zVAC$aUkKi5?ujW4%L?>Hxt!Tmu6Vk{V49Uo)vYCaG$E;-S2~lBL`F<(wd2RXRJ?9l zc&|Y6rNCd2<@!!{IbjMIT=TE^*wpgb{r0R#M>J#l)0A{AQo2`*v>uWXgteNPLrTJT z1`#PZaNX9Ab4}*)KCaOn--M^{Si^FfJlLC+7ggANYu$fAmYg*#?(7hfu0m(Z$~ zPcxzS{2BWVnL`)M5fENE;y0SVGwu<(zE-0vp_4CZnLIl(E{8$ob+M)9kFlvK%k`F2 z|KGlGJEv1LmWl@0uz0_RSEEPtB~?Z)3Fg6}11AMctvTf1SDXrtc>ve6C)_pm91p({ zqH^8NV5aeEH$+T`7o@3UEC@5XZtCD?(GM@-Z(>121tuS#(HN$u5~d)L`I369Xw^z@ zA~E@9#s9tP9@AeR%N{oA^NYyxS-vMhO<}2rj+PurxE2?XPeve0Uru3u+1B-2ejB){ zYQOE0m;D315?H_bku^1VJJzU*9eXREO%?qsc^Phkd^9IV5mX<8D}#+`jvsy;%Q9;g zZ0(*L$G|XZ?rFBby`6PIsk6W2n3={ddW^HJUKQt;Mb-bBJQh0 zjZ|h{+2$P|M)O$+EB*(3->$hvz>2LLu&9}@eLj^*Y6wbn0m>_tG6pK#QRWWGQ0BR3`T!n!VC9`tQ=Fq z1Z^`XtED+%CK2S6rviL8Mo%m-im2rGi`5f3-h#5V_Us$gOjXU|mX~Drvr|V{Od7G>g;uR*6;us>+j@56T)jKZ?Q2PnUwgaqGUlkx1{rR% zn>XJWd)y3JYDMys8zkb#PqpS0YlIG|+$DmWN`S&~jWy1GSKC-ncQjjj6VQ}|8lPdn zTjl?TceF}SkDj^y`k`pNs1h1#6FN{aa_MslF!b5s_^bjPr*S>g%-Ye^KHq5v3CCR;-3TQG_z`k6tfKacnw$ly<$GHLu$Rr!}M#5*xUaUr0Qr zEw!^2{ii8Uab{zTgOj9BFN~iEyc=ajPwX5z=WTQoA<3FY_Ok9R>CUCZ5QA>3-qz&5 ztxul`L{+Fceq&sghPQtWA^(N#5OqVPM1$%<#EZ?5!eTVt*D%Ml?!OtJPUBrJc11B% zJ>iT@mCCo30aOI`==Lgw-{P`si(VdvU~WVwMhRZjZP*ac zm~ivl&vQ=lBIDR(ZCCAXi7!jh*PJ*BDv#!thL=kc*8a!uCpmstPFu};QrU2MD_6od zzh|0gMM&~YjYfqp3a^&g!ka`3MKJ=SV$_BjKH5=ooYM*lgr>1cA~7!MPSeM2p?j#) zYaPr7m9zm)1VX^B0A$fvOA1M;&kW_TQaZ?^Twufr7vGtJc8Teh+U4~|ZtNuf6g0Qz zYIgU^(4W`erzWGklU<3hQOXJBc)ThJd=+b_-5+UJXrNjNMnT3DLzN+!bFb5uKOK+d z-eK{;?VzI|1JaO6?rL_m-;Vx)a`ey7+0W7<8L;Yo+#tq5R+6PnBrm_3iLKVqKQGOW zN_SPumGL~l!>0OMvKGdKkHZ13#mOY*wmS^4aJi2#NeLl6P91_hd;}Vs-k_Cp<%%n1wOo^G>X@E$ilB z@-i%1lG5XfaZ28vrGXz`m0@$wBe1&}rphZbgBc;|#rmR@bK^cQNhc9i;@_9!$7x_$ zn8O}(dtq6B*dHk&iz^1i2ds4m3rJntOv_o73o%uvcvlePevk?335eCnA_$RCcrDt@ zuR<3epJ7Zfza7UzF$hqgAVVlCN;lYUUYD=cTXV_K2U|W_WZ=7r>L9`fSm%ORzZ{=P z_(n5chfhdqhp85gVQ}=vzI?*8{pDNORF3Q5!H0J+K9cK_vH_F%9roWKak%j1UT-Dx zobi0d&fqTBzge{u?mC5;`5oY55nc11n&~*Tb(BhlS>+*2q|+z8O}Qob1Kl(?ISVcl zclDbqGxsfK?ipq^2lZT-;ZFr+D9OL3G8?lIn&p|6HF_B#m5OJ@5X8cz-H8ht+>cU_ zCW7Ug)t_yzyYEslVF63O+--89n~&7uQtS%O} diff --git a/screenshots/contact.jpg b/screenshots/contact.jpg deleted file mode 100644 index 5b3694c4f8d120420c5ba30291eb80f0f7beaca0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48549 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 X+`8HI9_>_^b8TQ?YuBvmm(l+Rdx+ag diff --git a/screenshots/conversation.jpg b/screenshots/conversation.jpg deleted file mode 100644 index 082ccc01d9298dbcbf2f9d690685198808f5d835..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55947 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�fB|NMK+dOl6BcwTj6f^sxgOH(Y{&7#)_%Cq)Cdit%?<@LprY!>T8W3 zNk3ezZjDrHjMyPIP`XVKwS_TNfkDTxIJG|otU+&K$6Jzyx9QbiF^NkLQkBVm#7X}| z^G#2W_I;p?g7CZCxp^aw?2mW;l9)|CsJ_MsZX@snJ8epMf(8i6FiZ}gRufHANjwb{ z7>|r*87)03eGz|;55v%+n+{6MP)!Vx{5II%y>eO5J%zI*0{rXSALjbSPhaG7-8}S7 zdg0s%`eYszD8J00@oLh@Ec{f)&K2@`{-Pq-rcFsBk&26?j$ru{<3p_%Wf znzV)`xkIG{VMcbSh7{O6O2>ke$7eC<1o$M$)on+1NtaTiM4R|`KKxh(N z88CDtETGL%FsI&hxKlJ3Ry0IIj0Yg zZ>%P5VkIs^#wrUeq5)Eo>}vY-^f00y!6Gd&+jXBSE~x6PcX>6hRPE__&oG*BtW<^LJ4C`n^J|$Zx8~h{jDYOd^>Ar^#w-qAel>f*)b%faP&+1k+;Wy8usC z!JEH$YhaY&vw*q;!7S7asCE58qf@aK_9TOq2AU|n3eF@C-Nn{dcZ^>-lUr^q$Ad1s zH(SyH9kULmCh=@cEo@ZHiJ4uW(M06FWqX#i!giaC(qpSeF(x@y$+~=_aEBlp#%1kyZ z4&7KMQO+pLugi?4cH0yC6bFveZ~>RXjqnGAE0PC!l(4y|}6YzcPu6Jd_G zdCmZBN9#8N=I$@2_A6{ZUfyDlQ`YWX-h9@_#H)y1Rzh4FYk_><51_T5tT1 zUE@Nmoef+!_^Kc0tm%$)9EBd%Qd}w|HkiI!!}q@9P3^OD}^R&&Xr%>XbI z+eV$+)XYCYy8NWz)Lua%Wms`fq-GUI zu7{dQO!J|ON1irZh_mXbNba*8*D#tIWq^E*2<>=>EMA$ebu5`xC98eE)Epdkm7wVF zH4k-vBNyy**PSllFXtUH%^Rd-6qawKQbG^(T2H>o9c7tu`+tLCpd7ChP*fQ!OK*IY zTWBUzzTGVEe7m9~=Y+V^O1Ne2!^^u9x?(bYZA7jjL^~vtqN0{fzTb*yh#0Rw(zctxA6u6fZNf zgY#SeD#1&kTNTiy2d$|`|MF*V|3&A-czY22|I`z=93Zp7hMEbZ*yJKmaUUp(l<_Ph z@bXscis13V=booq3f{gi9y2y&8o^js(;ZQY>4e1r zbj7X#vyOKLY;c`I`n)JAb%BH>}YT_`0Np6g`~sDBi1B)A+!9 zG!?=yHg&jRA*;QXtCfC;WLzNd%3TOaJQJ0(jg3XqU8l)X+A)YtElRlGBhMV)|M+Fb zGfGwgv#jfCoS|Pv8MeXF>3?Th+8DMg%YnE#U~1=6-C3(IBrzaeDPYZx5ZPT~^p``P vpM@g^7ljecUv(b$SXq(C*;E8ckaUAxr#^h|NtgwL%TyB@C3o6;e}4O4c@4f4 diff --git a/screenshots/group.jpg b/screenshots/group.jpg deleted file mode 100644 index dc24319d8eac03eaaa80bcb4e149699896d4e840..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57382 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

nWKK90@bAI8++kyfrk2O}NP>|}ojK)h%Ux$`? zBcM2q1pTWXRb_B4!KT>#vcP!-7emIl%ef1;HcrhY^MKy`*o6c5rAM<)!78p+k`)d`<1x!5bp%_hufw%2& zG39=qouzQUhZ6KQitTP`XXbz>Z3n#F!aSV!V(oqXmmhx^ER&f=6s~=S}zaA zU%XWBP5WzC4;L2?H#>q;Uiaypi5Iu$eU3a886ue7$1()YL7| ztxMP6;iF+US=$q`D2~FH?W-Erd>=sdpV3RSKB>rvrSq;5UmwBJH-@g|Nsjrrf{u?? zC;aZCO;lo2l$J=jG<&wofarJE%69UJQ>3)toDO^rpRB-gQ2(XUY02`UeUve2AN1SZ z|LM2Oay&{!Mj2qFndu<33uF4T)B}zk&{ZkU2M{Hl2F8;$~U~LE4K2jS8<7#$Uz?HfTCsat( zoa`GfX#LP-X?p!~4xfW-XDe`g1@x))Zo|avg+?~iUL5ui6;ah3Z=&;>*6F|KyjWT5 zJ8r-JQ6|)zuPopccj%qEG1m=wfGvK`rG7emnzfc{d5RDFDb3d}&;GD{Uhh98HiRm;HZho@HdsI(FH!XUHoexBoZUR~FHKj(Sf=kIu)=lGp} zI1V$@%;-Dc`Fua`*E;d%znYknDk2-c-T)^Sw@^Z-o${begTEqu1DC|k5~c6rZQwtq2y_q@qU#Rp4wLX5{k~ zB0l$CIG;W1xapFQOei4wAm-2EtWQY9QCM~;@ly0JEHZLMDC_{33?KkUo1qN2cTmJT zhuiqX>yYoP04#SJP=$a8>+rH2TP=*Yo1R+up03P^1H1?m>((17bKr9@(s{!woJ_sp z%vxgk%pn7fI>U8U_TUR|Lk`S$qyqYVt|@yX*kMIbxmFR5tW1u)y?XbltPlI|sOQgu z`8wt8N|%MDE7gU!4m_v?OEJ>c&*qf`Kyh6eoXMFdg$^g(sO@&(zYN!bH~$=S&WI{nPchem}`s;OCSyA?L(wpJRE>6O~dRABJNG ztv3k&0Et7fbSKGmYm45$y8-&Y++6ryxosWndJ*yUUmi&So-|lDqRtPo`UqKA;n8h;!au_D4-mjc!Ai@Ffkob5Z z_VGL0qK{u!svNck=TPUR?%mtn(1};I5*9TJ6^$7}v_gT^k#-g_cMnC-1^?r#nrt#1 zKptij!nahLPrPb&QH`lQ_^ysmEh8pPdYt}ZR%D2UvENiM$L)}Fip(4+MiZH(t;Cn2 ziDe43xE4UN*li z@2kM8Qt9Xod;|2QZ17%&<1@5x8W+GaOm$N-}vU zfhDJxzck>f+xDfF3xVYv2oA#zdirHY9mxk;k}Og22jtOJq5^vOz4=B)9qfL|Jd}RQ zcuhPDpC#x(n>)=szRus#faB|zPMG^tY>^;+I3d(K>g%KWe!cEe!1;&v$$?F&oEzO7 zCU;*Km1nE{M7dt6JRw)s@gmhH4v{C6ABKNu7Mcp8koTwaB4prDp?kAo=!3Qs;kF+j z&KFR2X)Zzk8MO@TcO?h2t=9buySyg!Lh(;;vo+r+*9LJ_?4z(oc#eGw?6R-SR6n)B zRb}aQ`$$#w+T_O~$!B%#`J!{8Jp`8)b`Xe3&+amEj8 z+>u<>73O_y&Vf-AmxC@1UbOM}pscVNS;^QbGPHFO#``oPW4@eS`B?ze3f=}>OVP8m z;#J>psnOwEZpX;Y@LhY${aEzc_2iSRZ-QUHy}A3Syfg6D={q1Q5D=MjIpfq{@I$vy z@h_$c{g1!u%-4Qd%Ni~_?<4W#KwJ=f`|%+#V*C}v6e?(yW=7bbZL_0CUY|{0E$1fl zrKi@0W%W!-A|8Sdc1dFbzUTjH59VG?uFlRLIADL)Ny&Gc;~YuPRmq%lO5~hT3sLbW zjm@K04};6FQCrM}!8y2M3A?vOXrXAl2C(&poU24o7_ZiSuikf$>7{)o0`EUB@rfrs zy!vw(xx9JI%5^=h^c;f~mg|F|Plh&2w=Y&btzkrKMPIqfvuf!~Q|PEf(Gu1!dqsX1 zD*hF=+)*=LqnB9su7-Z*jN!c$!=C!Xh|EvZ=TZDhptMn?g+cZy4VusEHJK$}Eh9KW z*>q!W1ysh$-6z)yxFGmo-sF+Zv4B3#YZWXmfY4dT1u?jtya#}kp&2tDv0_4$%bul1 z_plATpXXCcRtr=lpl5F9>i3p!s7HujaFD`eTStD+WmmpfiKkDmJ$(YG{R=Olbbo6(BRd`gnef7-x|WLxV3& zCT)r4G$qeaI_TM3RaALS^<6Ex;WD>)8Wd*)s4$lBK(@wQVsI00H~)6<_efc@aGkI= zEq|C>O2OF@rt0Lmt6T!de9@XpeFR7^Gu^VX8!5cL<&qAS)Q5_0N$Jz2eOeTXfrY<%CV|PM9TF?=G|8 z*>^=cORpyg#B0tB$X2YE3=x3T*U#F&cnpVrF%8Omhv2|~ZRj(AAvY%iFr@b^K_lMj zhz5!$1+K->%V-o}u(qH(Yc~VN-{w22q;)zeDbVyd^--vkk@G>3`Tmnv(GLQk>d05} zmm)4m8#7rg(mR~v{;7Zc>Wc?I`3&+Ha;wfN%bGhd~iAV^xuBI|1eGd?Opu;+#L$;TK?Bm zk15|tj-s$S#~D4`(>f(ie_Fy9o(7fw)r#?Na6P{ZNfErFAZU|8*8Dx2bT}albdT=t z|0Q=2um1r3lF8unFJoAKnUtWd%)8qAD1KRoon8D^>BO<(0nrmY3@p8Wp1{FF0GfPt zK^wGw-P*r_#r;LMn1k|CM~_ftpqa{@J0fR?b{N#yRtHT8`aeLl^tc*gF!lEFCZe@5 z{hv4;;bW<`CidPL&EP^IdY9OGN5Sf;ts#Oe273ORhJ5=-5RY?&mF1gcb^b{yG-N(Y z@hY&c&iep)cS!t$e|+@@v#?{QJ$o?#7_vdk(fTRD=5#4k>Oz^sJ(d>o z7^np>F<#fo$Mvdw_LeAJBZ6^h=}zuh<2$W;FGQaXUv60Ck*uS38LG&poVVa{$+>dF zhIB1Vc=yJFYzX{1zU@BVGY6_Z=W~lAnnAQCE^n=7nEYkQ^`i@k{5&)+J#%yI>T8qb5)eFU z2pX%%hEwgRM+VLaj!B32QrkP7h7A}WbMzZ`9LNrqccR(SI;r#h5mhQHmbXfq=>>)T zYmuc8i}hJ{d&N_u4TcLhQiXOFI%-Og0Sr42f)YfWtECC@ zarlcE)IZFcdO_RDwD*G`tBHt%^^q%xZX`SQO?lToQnY9J>2v3kwGH?fAaqcG5|5-w z{t9a38w6yqicSwL*^s&6>~?-tC?u?BD*Z7xd@=Z87i|z|r_E9A$o1E6TxgFVfel>!`|ILe+d^f4AKB1=ce8(RQSkK-V>P@hpG)KvsjU zrq^oz?RB~f1Zk{TT;95Dg3$|i74)!VagaJ0+&)3P>T9SKh~(2JuDr4rvlKAiyY=I4 zCmQPE_rqGrg-@9tKG5KL>WuGwh(TUX&z3%MHr>CK`W( zI9I7a1`{yE2j}AbCpTpb-KcLr_8Ukq3 z_P})BFYwnqa$#QU?IS(O1X_E$jKC;ZiG^pL`=QR|(S#?i>2)N0R7dcGmZo!~+vcNH z7tVIBZH-&Fo*$mNv!i;Ail(41r|5MUHEH@A*XGh_(raBjz7U@8!U!rnLK~+VB8w^LC@xFnh zyXoJ17wevg;j2&7t&I}iPe4!TMzszbh%Tz=N6lRWy5mms>K@ia5aTq?>(k3KW_5Fh z>BjpC^{7yAW0fu_>m;fUTbD)OP3xf)$=un$IaCteEOczZzGUmkPkh#D%9YqaG zZ-Y`06fTuy<6YH9_Cz`Eeyq99$#C2GdH=K8*ze`<8*<&366Lp+S&@Zj<8r~(-v+?= zw?MAc#MT6WuW&~nGyqvh+|;|)eo^sH1_nm7D}!2F&sSGhD@R?U;TA#~)P4{Ynb`di$?X{r(#yQRzut|4&d1Uh;Zt^0a)RmrRMs=L-~_=^#JQbJ#*WncyUGsBG|>*dz-OH9YXzdRo@p9-e{ zb`0qj00&g_6SM`W82V*VKzzmsP(_HoLj*oC0@xz}nZ%2;giyTaZ+4P&Pit(@&bMz; zoF3@nomOpJMi^@^ox`U#ED{QxoSlok@_6o;Ga&6j2q9d*^vjn?+l1$Ty1Ptw zaty_09}E19vynq=qk%q7n+G@9fYj*g`h-IO(}hnEE)%RL$o3*_N$F!2P5*9$yPl712ggy_738~|I}=)d3f?<0H@+@-xK843nS zIU~7IA!NABXV4r-{97{%^y0hUtjgR5@;wXFbOpJ-O@|i{ zDvX<7*K6z4iLG}q{R%|lRkXtu1_Z4QlBJy`U-1g_vshU+L>D3EE8wz-!LexKDRDf2 zhW-Afn{=|8dQa|jqgEKecq&C+A`dgb`X~X_Ntb-gP}LrtW9FLu;Ur(srF4tR@NjQ( zd@=kAo=Ti?+E_IAJ7Z(XsPkece}u4=)Bq4$@2@2lkyeFwgBC&mQTPJI%u-l=d{(s1 zYDfQSG~t8Z&{k>3UD^dD+L}JNc9<>3z%-b)ar}_ItsWfTIyE&Nd@Cj|*pF}S09(_9D z&O%+;1NJyjW+1DAYQ2f2ZUR2`GVf}hzV5j$Cs>yjPPsafmFHXxXng0&bKb>w-`NxlbCuK0+tmY@_J9H(cT2B4MEeP z>_C?(B6htw*%C^-hoHGsi1dlNZC|?DD>|31-Jn~eug-drHdHr#iI#OctR6SjHOnba zeSF=Y=B6~?@lZt`d~U|-i2al0RFNnsA#h&3&(}>7~O$+-rUno{NdzP{#gYIrt0|OWxz3=t05j8T0+fU>> zvOjb^og$3tH&9dUoTP{u(`x-PD8~f2e@}9Cpy*&_;7>*|+IlIMR8@MgrM|<^$+R;4v3YM_pzN|sM(8!f@b(UAizmc7y$e^>%YT`UeN7$9fVq}B7 zO>wuo%tVGoydilr>YVOZjQTlN-HSX#s~T!Nv^L5)e8Z+y!jhJ!)>pkP=3(BNR&!mW znZ&742g^qP&sSH?#xLo5mPx&$X?FY>RGti4wfP;^_pic{|7e);FDTkSqCD`T%PFE}rn(zwt*7HUq$TU~S&649_ZKJKk~lTquR-cP!mfin zRj5Nm&Et(t-~0P@G4HPExTkfI7cc?*<50@{#`S!hi|u+LFvJi0V@x!Pu*bj*pF5Z( zZ-F&#^kkvwW$0y<}%FRmQ0+FVmF_ji9aDgj{Sx<2iy|pHF3|%P}*yPz4ssOWJjm-?+cNesZ?o?ch%XU#c*GX2P?;-ziy?~`jL652Qi8e&*+BrAWIP27*^-tUP z61ejY0z3(YO|==pQ}b5PdG)1uCr#r=R`p|BZj{o;EcFy5jEtfsy%hzlVOP4GyOCq% zBxGDc4aaJDZS1Vl=nGS0RqSSN$!xGF--i)PwZqDq_!_m>0k2aAXUt_eUu#h!7e0(5Z5b{##%Eh6VN~hsrS3#{6mkS@SjPH@`S7aOjXG3?r(Ay8RH1I+ zKfj=tz?b6mwqVif_NHkw*K;WVC%#A!c<+5_q>9$s2pd%;RwVlh&i7@8{MhGPwi8|O zxPeGR2LRIg^2jVyZ%%!pak+)tNUx>~&BPaCr`i%{*suhzsPKGPy2DoPd#Sd3W#;t4 zu6#KQnvj7+7Mk3V0kLXo@%Z+|tw&Rf*3OvLNCX7yV2u*e7605+bY>%{cL8(5YJyDLsU@yq8LBysUsqbkt*U zCIj`kqCq;u*h>33xSd zcXzmHsSdA>#T<9oE`)EMnOQcDT6Idmm=0F2avNK|zi_e?w_}=0I2L6itBy0zH10YR}<|st}CAsRJ3aVJ6*ap7n$$1*`+eb^j(|^{#h@%KXot!esSd}D(U?D z3Fgmu&&`|!Zn&kPCLx9L0*8ggaN|H22ur<9P8`~qnbvrW6TVYZ?aA4}fwx_>jEJiO z27jAU3_01Hb?IrlH6jas+cn?z{>qHP@H3>tyj4@ODao=%l140&^U0xnJhktmipAZu zvCT*K$p>rLQ5|%z;LJF>Xt=<-Gk#ffSX3Tom1z?+j3qO-bffdU5@%->M#u-fR>w5l z(84FqA)=sF(QPHJ^NK|*p)XKWFb~tjhxL`cN_K9{RT{7yZxFvL2UvvAOd13A9J4nT zzQONS?k`6cVff1KoD^5i98J0xh>(PBO0ovNc6eTkLSz2^dT)!-$?TZhf|DLa<+1ru ztfc)uB!H0GtF-p`9)1=mk(vU0vQWyc5==Z?bHc%gPj73p>oOFS=HIljGZOvgx$6iD zIi6Kp<-bMgu&kqJY4fE}Xv)Ccx7S}WWAQ%uqG|^?go|<%VR?acUOC^tO5sL(8j};9 z(o1XCoN1$u>}m9jv8r^xE1x~dE{98I3&6@$EcFjE8vJ&DVET zDJ91EC}#ayN&sE1mD*NkY9_1(0|{-=p4+^%MqTeicRzV@-n#0w#wnBOVrn;MPRIAR zx&;S@K2{5_(-zgk&umyI;BJCLX3hq6J;XC*5GZib9oid+b4qTftGWWsv8~hg`$rA3 zkNZMe9|+4P%MVtW3*IuQrer!I#g3?dh}*Blj}=ZE^CjBm;EhfvysBmtQ!73WyAO1Qkr~N*eaoLOs@HhaP=y+{ z-VwW)CO`MO2lpx1nU*u;)7Q@Dsu!>ebKYjuIEU?aZAN_lBOEGRTx3FvJt%)4*3lS? zN;a?YAHV!0(zMz7hK2;GKm>5wLO~5mbLo`u4s=ijj_Y)K+Xqv8+Knmq=ssDA{$eu~ z(Q(DnU1s{Ms9fJ-?Jw(h$C}t-UAkD7j;U)74X&lO2_9&f{%L@3jA>AC^y3*G*3(sV ze79J<-tE$=rONyLPG_Jy6NlFVr}Z`Bi`++LPe_D6AFySR{}(kYKRdxm2=4G-;zZZ} zMVu&CI(7k!lNdaa03e$6ktXfCyWn7QFdDKCC zbF5(BSIhBRr*ng!MV#1UdQO(`;n?)%Stb$l54eQ%ePns;<9OCCY2^>~_DDH7HgfJG z{Rl)GD}e#PknFb!)J|CBsv-@}L$t-J^7-4h-FKG zy5}JC_1WMjcHzBaB5T)NBH+=1BtU&H5B%oD+QEhl&5$?$=wb|2F}i)@RTL`)w~i`?f*_m;{W3TgR%T)A z-OLrVS%$cne000bjO}v+IBN>#(dKUZIDfMA3np5Q4XECZRhN%d=i5UL64Y=Il4Rh5 z_pnt(-$k=JR$V*=q5`@#B6IONQgTDW&t zRCx*zR#OPL6YxR(RQ?)C-#_EAZ(4Hz#8senfclU}e?R>9Vfo*6I*{W=j_+ke@4v)nK1+88JT8XKz5>r$?UJ1T2}o%1PR_XZlcHLiNtx&Wf}J= zM7A1H9!K3y*rt2;+34Ndv)v)d^b_YBr~N8Imq@0BzL{ zJyPu$Jkx^tD#TnRvQ2}%M)SGvtw??F1AhuRHnQi}_2*B+OW;5}!_Hk9#4!yJ1evqH zcZdvYAdjDOL6w-Vx@fA4a*Qb+JUh{71=CA;!yWeSIXJ@ZimoL@+PhgsR~F<5kSYkz zr-Qw{@GWzQjTDV;`D+)dF!r)-Mp44y#~O{YTE-qh1`cx{RijjPd#)#OI%@W~$3%at zIC_1Y7Dm_~huArVjB}kI`##lsgMy%*$8j<-UVs?|E{L$8Syl7uUFpchcwsy7*Lbf?ajrMu>o$_3ed|92;b%DmwThM|fH|vkzj6*UzW0oQ~&s_q2rY_#}(q zgFTpI_QR3MR0m^vi`;EDWE7}%YBfSLg&DJQbZ+gZqy}7k`>qgl$}@wmb_F?bfn~n| z7rz`JBl@fpeFD%h4La3{gE@F7-Kd#`J5h3Jwih@}6pG)+%7>ZON;q(z>36HM-UQ!M0`KF?~(RL3|KCe4u6T^`qlkdQJoO3nBx_GdL5 zW6Vl0Upd-}T<7#hpeFVq<1-@|!!m4W>o<#f?D3BAX)XDLCXt5m{s;^f3(1id^I*ZT;&m72N! z0p`_fP+s{`qyH2vvN3h()jc!YF^`+8F89K}5lR@jRG2?TN2gblN5k2?Z{p4d&igp2 zek>a*7IT6Ry3IElE*m=Jg@MbfdQA84Sbf4kVl<^jSA%CObLhOfuEO%)#lN`OaO~DG$?pqB{>%eHK{Wx4rYomoq;_Y#H zg$x^XSCGsF$J03e+;$IFGuv+r)#g6$r=C?5uQ5?M>8X6W)(kps0=kn&A$EWULpKds zVz;aoD1Xi3Il};leUO8(PVlV&1Mi;U7+WXyX%P9gY0tv*GfgFU!G&#R*t#Z;&rGJG zymHK2w#39%5@B75bm9(TwK|(;4o;UPqeuHH0P5#I<%9Tl{SN==-TDjs)JskjcsPX7 zUOlHWY^ z<4vw3k4YBjG2PTm{2T8>v{!F6s<-|N)-Z-QSq=00Zdkjp?@e<$GSWfCy`!REbwEpQ zi`BcPgEGYsYk$?JQKB8y7q3x&+<7k7z5XwdN5rSF|A9Pu5Z*}C>;1w^i%QuO=*tEn#d~_S;u?sueR9iRhUX4>lv-VcDJ?a{n^OA=u@9WwQcoqF? z)e=}*=&>R}?sFctu*Uz}OQ$m;U7D32Yh#Tq>r&CG4Y8MQSk{SbheG*17=Zq#-{8l6 zeB?Zs-d2x`7k7Frt~##pcF|X3vvxgu!^flER#t9yz0y|MeP#4Kr5l^eoa{&T3$(~K zx}YDRN@SZjc4iwY+Btox)8`)Tc0#n6*PHaOrz)ctq^JbYS>*Omx!~dLvYWCN&)Hhou7L=%{zv8nvu6pD&^fQFoUFckG2_Vhll#IihNPyM+#S$ zHZJbG*t{id{O03FOG^{e$_FZUYx+8TZ)o~F1aItObw*n2Y64zFliSv5rIs33HBNr0 z(Xd@q;SQ4OWY%2kDJ`kL=xgqBTHOaLJP(k8tszY`gQvR)yf&Zf#nGJ8cd^qY^PU1v zOw$Y#Uqq(%8P<}0CT~4T9h-^7)?)leay^|3d$VS{O1qt%-E!N+)~E7n zZk9XIGle z4$D)B>K&^OIXF0QM{Vjo%T0dYKKRkR?8{l_i5S3$;yy~yMb6f=Ls(!>)@Ctx6j{gk zP^huuEKLE;W6`cafij)qejzEo*wd5rG4FhDa*R&Yd(&wH5s8tC?AT|A#POl3R2BP= zr(z$6dQ0RRZ@Wf-tT?VI*l&tL_Yv4LjhL4J;dp9mNxX{ML1$T8_VkP6@RS>{lFh!) zmrp5&+$k+sEd2p`8_=mh*JegLEHC&HIlKDwws@$_nbFdQP8zaJGQH)epw^8**z&t~ zpUL0BhqmYHp#eu*g$t>C>v{>N1WO#U-?ThG3VvH?DY|STEhW7X7Ax2jH*E>_uW}-X zmF{A!L*$u6-?$%r?N}Pmr7fE7XfkjEGaAfvd`NmDaTV>;p22zTk$?mI9lpMq$c1Yj z8fm{@iCgiCY$|f}>&dLEntp6ey8T{a`aJHV;HH@u!WtPgY?Is+=W%-M>v#=3Ikz)k zp)c0%);{xBClQZ3+YwXI3FqEEGAUqv`iZakj$<&Hget`+ z%q(}X+#~JaZsUt7M)tHTR1#7^cYTf)-wG{T?W@ zHL$qgx-eVs(JUb{z#elYnIY-^`t0Pn?#GWset?_|vS9p@Hyxi?Dsw1FRM2dlL8H4i z^*EL&ku9-pvC6pYZ^B932AjRzmzL<`d$;0i9ePKWGU$R7rD0*q?I?C4hy7=8C^My} z+e^OZtNWiTB?59$1pn|m8e8kUS6u=_I*d-rylpMG^5-X0I_U8#Ys>S?VNCPmn+*2H ze$Sujiki_$(C9P1c_v40t9nt59Gq1Hr6FANcn_1(i^*q%G4>M&NjgWCjjFOevz_{n ztL0iacQ=iigs_mHhR3<~>}JTPN#h%rM#RJ{l#SCXv?3zH1y2W&ejt5KIdGX2SJe3# zR{gEZFn0T9LYwlKG_7@eg8su#Me^fC^QI6DKJ+f1`toyj&73&j21aNuv_kWw^n()) zY%=n$|8W7niD>Lu9dG!+q2!53z3->95w&|~>PU{Sdn-6FcCgEgK!M2AetBD2eGisP z#&0Y4qI)&$pIQmiX!M@eZFyo??i}rYhr*8~E8;$B!T*9*{grC{H)&RAD}9#$`k;rm zD{+)Dy>Znve=-9=+};pU2$xBLise7;6$4Ub{D48DBKO_%7ynb>GBq24AZfUWOPd+0 zs=f4KRD@JSR`1y3l|^hsF@@D2Zzg%>;_@;QZ$3x~2na_2%K`iea*c}ur+v9~>BaMp zg&zl~2ERIeOTI_Ew=hdl@y^Tv%JRzp&84k$N#pOfUkF`UC@si*fV=<@e6D$Lau^o< zkFQny0~FHn8i>VP1`xkqLUc56o4*~pyM&l?2J8yETqq#p;_-9U)<}aGU$>+Wz`xqx z8x-H*m2sNVZ@#!Bz_)M9*Z2&cG_M-OR%)2+<8gtBwV4n0|l~|HJ0%=A!t!8^2}N|JhIf_a~)&p{14HWi@X4h-l|Dq2Mo$ zh-IQvk2sO1(k6puy9@xk2MM!ppaf;`V_-v@eu%n^!iNoI`ARjl0n${+F8l!kcityx znTYsC$N~@sVU;k@z%lJ0;RmSyP#H-1c(Bire)t2FvI8irLQ2>#lit{nh3o=N5lbw9 z@Kp8hH~jz6A%#Sxqpj`|hrvwoZ)>?kCX@u&AgjAB&K>_AF!$&6fH-gjg3J3N_Q}kU z+ox|$C=|_S^i<&V11;(b2@-wzvpH!20nurQ`33^8M%}79I3b2LK=;4#5e$bXXcH1-di?KF87d;l&cb6QXl&_K_xHl4oUb;CzL2wYTc%OWu^?lhg_HjDXNjrf z9~7PPvj30tWjBmRFxykpgcB!n7B)ftdfWVU*YAT=-rD`H@*`^otAfe^Yi5hQy(x4V z86$52s5eGh^xciPD(2)is??#nwrK~Cn9;Dx5k1P&qq4VV9*Ve>v|=q(^l6GEB@wBE ztFG&H!k7|`{f{3juxZ)OkRW&)#z*d}XF}eh$)uk}$?fa`vb7I47>2jCzxw%gBQpqA z3#fB2@ecM|rg*rkm*`Nv1OcQnv5;!bTbR&sih9h`z{M}NnfQ5IzTqbjgLQe z^cEW8XiI1!!D+=6Xcw)C+qxXsyYN&8Z+J-N^nbW*F&M@7?3DY5=0RR-4Ed%(6CIu{ z)7xsKxYD>#M#DYXRPor@nB0Py!Lq`c450D^1;{`sG1jzEl6@H_tSM>}HUGt1Xoed{ zlLjuU9r4ym=HF{9txo*V7-|raSRKbY$3Q`tTQWTJfUkv*>Og$*V4*V@x2%EVs>%F1 zsqK(wH*vMP(BaadW`v_fO`2QxmytIfN?qNR3(24(sy~U6{AbA$e;hs8An<%fq6wqo zL?r7oi|v=}oASMo!@1dm*&iUIk50eOuLP`*e}Q~!arW%WLs+y9`!h!V`tu&U{Ace! zV>=8JW+KDIUXkiP)l~kgc^{ZL(e~tml3G zMxcjUdYOx>ttY*sJHIp^3jyC^z?j^#^A^i%lpbDoMS7pZarvFzY@bLt5VWRvb9hRp zuWw2BRGnZi$?Kb|QQr!IfM$v+0Ew?1nbj++s;Lgm^ZfQP?2@jo-i^(r7fDxx4r>I+ zxEid7y`eZn+YvFoq{H_4P*s2V?Nh9#{F3c>eHve~yIOqF+{-EZ5;2Ua z)@3&H%04YUb5j^eZ>|}atdkk$pKtlH4`}o{l}(hlrU1Ud%u?0g4&px>e-b* z^$zydb2@gJI47Sx_$RkkJ1%LKClUW!Ep^ZIZ7>#qQ--+DDXrM=XfGtB=NcMAVJ};B z?9ge!^KlrT^BOOc%q#0q?0UVzo&%;?>bVm6$sT8D*<%YNj=s1kfiO+B!;q(u3_XKw z?94@_fC7##xYT+~OyrVUyo}~kAQ|-7ZTzpXVC!aK1)CWEb)8*COSG20WA^v=*BzCMM|{#0il?9Hb}Q!9Q~~UF*ZnbX4hQUbSLcL#6Jr=&YrMi( z+3mTAMHJ z5sC}FCmSJWOtW|Vq6I*^{x`WvG2L#1VRhprx%LqH26gKaLzploJ}R7H%GST#_sP{( zkH^yKK1imk7No~ra;53}n>c9jmN)r4l5Q3K`eW_53|_?2zq51dVcnG$w{!Jh__(J(GP3iNCr}j4034=1s*;> zJ9HDw0%nAHGy|tQ@uCe7zFvpb4%xe)Lv*-j59jdJbmKdErX`x?-=i0HerM*YzG#cZ z&K@!s^#sLkgpZ!T8l4Ti6_h+o?0dhkM&JF_Sle%{QqSI(-T3hMnof?VZ^VM!qJBPJ zW6reZRb@2SDg+yAcfA+38m{45C^>D?su^o&(Z}K4%tT7#7hOLkvpPeDZGcl?Rf7pE zOfB`Aq}o+whDq*hr;9btxn#U!o_c4A@xA{3a@Jo`+x>?tyMJ%IiNhw}I4OFP&^ZtQ znJMk+PC1S|WC#5_Qi@-*Iv1!;Vox$4);Gi>#Vv{^?Rf8wzrgqLsA@}Ido21<*jMSa zIv;&nKJUmkI=uNTK-~=i)E(Rkxke<#aR_9-`P_yPcG05hm;M2|Geq#jumrKq@XED6 zc|Lk=UiQUEG*mAwxaE!h3LL<)RS8#|!ci+Wz<7j`oR|Q%;P*cvRs?;9 z0YjH|1hBo(Xor5MAmRbuPPHZepNk_SkQ;26);2`gvs=rt7vH?|kwexI8N9Cy!|Cyo zv#r-3^}o=av0Zkf8qvHYdv)j?4G7fTOd2H)gaFyP~zS%ORS-%tJfFah)Pzkf>LS5NY8N270J%3k}=ViW9Z zxy>2(4=elzAlGs1|3Yzg!6Oi{v`!=e8bS0;O`?By<0kmuh{@QE4nZ*yXtAZ8)Z1)! zV5{Q?JghPI;_m8mRA=q_#l$`*FM)Ltu6neHA07fN63qZ-!G8E~eKqjqs^>x(qMl>O@KgDJp z@7k{RHDyPKEbjG4S}gLDm&GD~>60tRyjnw9BE$LGOcc<>{t=sen3x z7doE?GC9c3OiSG4N>uhf#)0?4u=)U$I1dg`YaAgcxnZae%G5BUn;7~l0OO|b!5^=i zOv0=M5~GwiPZK@Kltxk!_(q75%JY#>!=cg)h@$HW)R3akN39(5BZGBS(-em@-Rw>})0N51B2W>c1{8G;)VEJ2o@? z+^OX6PJ!v?E7QaFug{cZc9eH%j5$evdb-Q3^diA&Nv0Ka<_lWc?cVZ54^p5)c=Y!` z*nj8ue-qXHRcQ1Vu-S{6VAZAxqh|w ztI78LteTirrI#uuXE>~HesW>uYVc?|)41C?%g~_k-uC*gtx;g@rE$K%1nn8Nd7pYc zS>31PH{yMHolLld=^M1MTPJR;4-G3dzPdp8x43!?W_U$ILfbTIxC}m$gsvY%N%-q> z9!th^*$!7WWD7U|@!?L$TkF^@eRe`w5$te4=&0A)iNAc!yF^-Ys&9X{P@U&Vaejf7 z9Pci2%;}$IE?$3*T1-{S=DFujxRKm5R~@DQFzDQlW4BnK!Q+rUv(l2(G}Hy{looqqhdGRL@s)}O5xF1J?WI0E-%)fO;nbsxR3stX!->B#$106|_qoS`9<}xJkZZ47~mOm2`0E`e}YDd-GTenG&=ik#crEU zUf6-6R!72p*QJXg%n@|yzFO1%B-mFo9A!9_+6)sIYChQig)kirLA3(A*A29gR*h6O ze5mUwpHiWrnV@$di#2d*AT>)phT&c3zXf2UTfNA<%>42U2aAnY6T+PxuJ)>JJyjQD zM^j&X=MdTOnLd;prKsWq>R5ZR4TqL&vNB!NowW& zygLa){*(ewm&hD1<>AOTdS8|j1S>z6%G^*VAZS-d5j9qR$#Ra4dj@Vd+Q>u(t0+TM z+2am$AHAl&Pu_W??@v5G>3trzG!y7BcfmrhVa#dkX|zF2eOXuwt^fI;PK8^H*HTH& z=7Y{Hd|QPY6WjH?E=0F#N<0(s7I^&9Id3&q6By7&!wwjblZnrgL+CSEIKr)O1bMiQ z*U^gayEfI2z{RDI<%u-HD`4wy z;dSRssoN6RpQhUuPTE%Mc}!frx=M%6s|tLOnxt#EGZi8_sF?Ga{Qdtzi2hTI{zrcP zpkV#K+&=t!q!nth#1^rCCg2C?u9z?|URj^yBdj%DF=P9w7$n8?t-9PdV5lN=@WglaJnzaJ#;Xcn0SWzI{0B<24IlH?KjB9>CsKP#U zeFpeIm4H};<`^6VN9Q_tL|O>YQx!`>{~~XAN%qzs+0! zS#SB@&;5sv_rH(T&oLf`*xp6p>i)pF@pJOhNCzgb53fPLO(*0;-=w}8IEfbJo6if|1UPa-PA^-Gl!Ef{dc&hzOFJc)W zj(4Ctia^r^SPBR(^g0ZpFT}20lz}Ceu zHmYccfi4^}5J%qHaP^_z(KoK*)MU-OUtbz^t#EPR8$$? zD#Ko-SL(Ma&9ix1+ZUhY^)O6jp6h0sql6_eFgi$fU8bK_D_AUODP4Gk51m(F?5xxG zm3diRF}C-`GPzlUqgeJ5crQj(g3I_`(Jt$O)6_0WL^5b|1*wPwj#DJ#{IJa|dcVda zc6}oHu`TVJTefB|s?xR{hkFlVzqT&$eRwd-n~H;UA%mLeu*^v~S>p!481%|XH}q-P z+LTs914UH5Uy?&+Oy-5q*J2z?>m8t%7nm?!PMeh2F8$A&4XRe2?seWr(`H;TTOy9n z&{GfIiYH!Z_mJq|yW6+om*iYKYMs0#&$959w5zbVfBsvn+6x7(W%Xp$`vnJAEk$M? zkZmcuJoErdmTlg=ko$j7hSy)faV=~@?v1+HN0-~W51S5FrT2zXSC4YMowJ-HiG!N| zI%9dX=?Zj6^xU&Qe{PU3NO}6E!2p?s3s@q>E|1l_-Fm72=Y-{<9bC4@q6XcC{6Fno zXHZk?x(*^DA|L|NK@dbhdY1qq(qs!8lx~Ppq+|mkEz}@N@2~*{AxaVHDj=OuLlco2 z2sISxC6o|M;jF#Sk5l&9Gk4~mxpU{t`Ikw)$@@F{55M})ekEJHQHK& zgfg|GQB?_#$8#zUQ%A=8AvKy3PLB48XPs1mpo`;2)gMs7iEsH*pwnH~H+*t@=Ug$#jK~o4Zy{BoPL(`$vqARi0wsmju z0)_9U;n_cp1Y4hPh)llCHZ7_1j@Q~F&-h`z+zoL^=LK5vbFD06_g?coh0RZ(oDl-V z)NX^JV928)+v$z0nw99LyJZEXN}Zk>qfaX`?IUO=@U~OBB4s!C7OtF5fp$j`diS~$ z5Q~dwZt78t)}dNeWg|Jjckv3oqeFlWf6rC(@~&qrZmdG;I;sjQNfNK#aOrEXQ|cG@ zlmEc{5#7f^-yD#XNM#H*94B8@q}z?m30a7nD!wj;*^(YcPgd_2W7kcBl#paXy~{-3 zd#)IcXm!4GgcDFa5D!A}ybFRI0O<u}Q))QKc_P8v z=bq$?U8bFf4bqa;@U_ukDc)ekF|w$89&rz&Ju2FWKYtW%m^<#9%Dz`A;wV%QeH<6R z;^L9lJVF@S4NaIId=^Omyh+jX7sbW|Jtkohz*B_Z)tqMBc;QdFpLu>ZaLf9vyyg{d zkLMhtTALVrpbRs-WN!nV!IM!_ydg&{LATEtllbFp#+nF6tltAf>s|xz^lE^txsr|P zWI8=3ce~ISiW-{OKj%E81l_$;e)5iwCrm^gMMn_q!3NxLN0TFc>hTM~&TSkuY7;y)Z>>NB( zpO~R}4eou1IyAP;v#1-VTbGONeX#b#W=Xi|HrsWmY_fxz22)Vx<{`ico8yIY^Y7|!sZ%Oi=!hfT*sre^J?XIg#zrtxXRlx4 z^KKSjxpCvnl_%;G7nt?v`MvPYWCav@?g!frY9|6H>{7q%?!-JjOnbD}*K|LxY$Wxr zB1sv+M9gfTOdFI_5{i1AFAh<Yr2GX#G>z16ovSTZsPOltzM0>-g`2i{9YkZ-k4zn`YW-klZ&Tb|3jgT zd|K+KyDIN~r#bEjh~QhZEWc&?!a=fLx3D6{Eu-k0B9MZKBPaeI^Y`z1{XfPI`U$XG zc-FX|rhG;2N^FqpwHgo-D@`nlvXt5Z)xpd}1BGOL~GA9vp({@^{|<0JId(QOqlQki;wB^FEPz@hzz=1MZb&OF<^Ei%Ap?XvOG1 zln*fW@4u8h2s5DN*6aYAv;3XpvCGg+?mv+{_RR+<3jaj%cszlf=FbF{f1g4A*8Z`+OxSb7+%S+Fa~_Rq@8rTcM&b-X|YRb>b)zVd19gX@O> z@~K_U!{BY1S7LUS;5=x_&y)8c_Y&Lr&t$dZi_b%5bJYc%6 zBLBQ*y4)XQr0@fPfWPQ&*E-+>d_wC>fS6VbC%2nKp}&sUy(&YMKq1{ER}l-KA;1p< zz3kul8&JfT*tvrp^}qBcj?p+SqJAJ_duN?SYtMaqL_8*`6gHs;}hX6hRh$ zwQ_;wg_%z21EoQN#apF<^Gj7{Z+jWAr+uY)O8=&H3(DCY%3g+~JM8m49vgNo^&E2> ztluS}S+>gjN8KJB^WJ?|7}B7@dRW75nLA6iC0f5*vk3fNxX2_hXgn%lwY7Z}6@Kj< zoO#lmfBK9gSe9M_u0+I!l; zE|I~*`lhZ!3cI}4kQWBD0s|NWs9f-Sw?=|Z7LqQl*=VMeNz|mzEN?3BK8U)zZl9`W z9$Y-r2KK%w@Ju&gHWTlO3#~7*g7I+1R?nE2jLD!g-Mw9X`8(z3v2GQLaEvwo;EXqd=)K1TFMI{(@N!qOA5xXW_S$B7U}6P^XqeDo_SVrh3z(1GR^c0**47s8r1)$g83k+lZC?u&fD4| zjL+FGv0b$Z8QafL<*JP-p!h8`tdr3vpzs2+`)49zS0q?rWE(V24!RbWmr}1t^1Eof zXY4rHsruFS=F(?BDbd;;HW6gaaS!)%@&dG>OAxEebRg(Y-)ZqK3`MWO}5#X?RFd~B&)d$@_61|2+*I?*Cb zO!F>CihmjxN0IN7(oj+z`JSaZGiis@w>;j3=&SZ}_iCAv`NpMcOfG5{yQqkJdq{2b zuS7mJPZW)L_3~xM3drHny+(DfR5?l}4s!wLlxh~iU2Oc?H(_(Ek{GawV1~Z}WTBnM z+$`QL8kZfUS7iCEHynFBg*w%%hec3zXXnIm-tkE7+(Qv%PK*i@%+ph(>Ycw{v^9FR z9^{;Ocm(Yn&_mx<=wy(E#W;LOy!*+MF8`vSl1}c;eP%A&sxv%IaY{HO_y<5E11P(Af5XMYjyg|TT>!D zAD7gNHs@Dj_o+LfMeT=wgibAI6mm@SB#f%8U;3^FaiaA&{Ve*SGPyZK^`LTe?jQS$ zO)}ht!LcT!A@X2Q>*`drJ*rWrhje>|o*%ZCz4#&!6X977)_za48)>(@W~9YAJ#FY{ z5v1N<7-xKcRBCL$b|A?^C$H|wRIT7El!aldScT-i-w9}bE>TmsyGSM)Ea&UIki_GL z!J>=bPxokc=dJEPuq~Q6Yt545En1k~bmy60#hTz1z7vpu;FMT6yy05;RM%(1-|3vU zs8xYLsvy70MopnPH=EjSmUD11^z5aN)UOS9&5k;LEJu*LEvs_-#=zryp^x8~)QvtiX00FZxEFm+#&Rzu&Voe3xgF?T`|FOw&J+-*c54^> z(a`V)m1weS(d-EOVU*0fF%-XOVDKGOe;;3_VcYl+`*x%#u`LzyL7M+^evpY{h9c(o@N2G)) z;VmL=S};7*bQUUVTgj-B2zb`o__^7snwf#F{OcF0hYS@Xn$XT*X)YSbTto{kJn^U< z!BM?5>^m5#yyGQ;wM!{*lfXkH*JSnj9L>Gt!98;lDUpx)VfDK^oA^b>q)FEnzDand z83fj4$2)Sc5gn|fFg>-F{pNn1!Q})8N5}Jh?6u}U8`HdDNj@mI>F*S{I@V;+P?54= zEreIx??Sw@3Q7Ia?>ygFFXS?xW!P6Oe@#s~)T_?E-XscHL*FXHM7I7$4p@}A(5j?3 zRw?bvuY3J_u5;vK$GBggjnyOjb&p|lEJKImJZ;*xfFdO~REXH|0DlzKJcG&QeF0hJ`1%Tk+kl(5CMyGi-ehavvUQvB zXSf+Hvs8>p)eHUaCZ2?#fJ->(tNMKbNfN9dRy=39)Ii4_9ms0LX5)PKx0=!F&!aor ziaVFE8y~glzUF9bxY;x}jo*UxyqTR_?b|M6bf~{S-Aqey*xGGo$ zlNBJ2Y*e;AY8DAz)MY^>Ob_V#opS-DZV`Mu-LK~u_vWK74Rjoo`8k`d-T~A0)be~ z{37-23`y~)*qsHfOF|EsM|>Spa=R}%I^JU;vt|+;wf5zSl>i^tChC|uOk;y85I|x@ z3<1eupB-@0^;9D|2DR*Eeq2Kx8v(Q{$CsK|sC-={IUt|xUqF!=KLKE>8(O$8&?-U7 z`4*r8(b_0O)p^4b4A4sEh5}GjQ^Z~-&@0`O65QP%oQR{w%23S?wWzw4w7?3v&@YIC zzg<6x=*_v=4U7-U!~)5wbpHt`d6jlf3%7#&$Vp*`k_*=nK)*Jd zoPbhb037B^tGwcLG|Lxd+^g&92tJ z*u@|B8m6)T|KC>7J7gZpn^2a}Z#Ej=8+V^~et<_}Oj7LYCsI4EOV6iY)Rh;BtD~(> zZ)W|Z#uqTw<7p5)`@n%2$5-0czfqdh>m12o%(a-e2w61Z6vfj1U z$a~=|KkJ$}1b*(?+NOcI8e1`!%;bc0BTR{wWn`<}@id%doRn}M=1VSo;7e`AR)g7Q zhg)}}TM0!Tz7lT2F@IOM+ZOMX_^McU#dhHP_D|_wCtgKKXs^=;9+WPpMT)JLSHKGQ z5g3#7!JJmSD9^F?mj$G7T&7VC?=1H4bIjz?$4o^g25zAgv^ggI(K?e3WIUfa7OZxr zsL-mWTF?WgChTf`6kHHP%eUpB)=i)6-SrT5Lt)MTo<8sK$J;mt@P#{(ZGt+ZUgT0f z<8wZ>W3DCp>hjayGem8~i(&aS2d)~~5KFsvqOjH3%a~wwU&0oxY2Ap2DrLF4lI@B2 z*jWu-N7Dx%UgsU>Z4MgyEQ&0O`UGi2ZPDYOwhu$Js23S3+@0Nrb(Q%cRgF?3UV~~H z$K^06&`1?6C=93$Y0BqS5jS!Z`^pk{0YQe|gr z2YxogdiIQZ9eVom*6WolGC40_Ve$MRuhE2kY2VMYgFPb>^RG*3t?gxB!rOx&0mu^Q z?hz7eLXD_oK+N->fKEVSzd4WqO2G+e6(G%|(g0&udm*6~Lr}#K!ykbE{ljO1fA|K> zvO7D?f7gor*A9REMg8a4L5!@iLP!IS6VG-iksbl)4;>yubU~qoMkgRTZ%X0P>8sCi zR!Jq3cEJ4X0p?2S38?KJ%8g>keSOC#;aV-;*0rxQ1WfqVa)qCr=0G37IKoT--{2!} zL+oB)F7}2g>rAz&OiE1%3~+o%I7_&U89be8C?+y&dXtVr#1uSy-8A9r3MeQ`T1IFD z@-~VM@=n`c(_rv}Rsc$S=jO#;i8U9|WLlp^xwljn!USUV3d%0$$(a@VZ6gJ~)WFoB ktVho2SVODEkNs@DVzWiMZy3zs3pv#z>8=xirrqRU04elao&W#< diff --git a/screenshots/profile.jpg b/screenshots/profile.jpg deleted file mode 100644 index d4bed18e67af1bd083754eaab39b47dcc2c42779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40582 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